SQLで文字列の長さを調べるときは、文字数を知りたいのか、バイト数を知りたいのかを分けて考える必要があります。日本語、絵文字、全角記号、UTF-8、NVARCHARなどが絡むと、見た目の文字数と実際に保存・送信されるバイト数は一致しません。
この記事では、SQL ServerのDATALENGTH、OracleのLENGTHB、PostgreSQLのoctet_length、MySQLのLENGTH/OCTET_LENGTHを比較しながら、文字数ではなくバイト数を取得するSQLを整理します。文字数を取得する基本は LENGTH関数で文字列の長さを取得する方法 もあわせて確認してください。
SQL Serverなら
DATALENGTH(列名)、Oracleなら LENGTHB(列名)、PostgreSQLなら octet_length(列名)、MySQLなら LENGTH(列名) または OCTET_LENGTH(列名) を使います。文字数を数える関数とは別物として扱うのが安全です。DB別の早見表
まず答えだけ知りたい場合は、使っているDBに合わせて次の関数を使います。sql length バイト数で調べている場合でも、DBによってLENGTHの意味が変わるため、ここを先に確認してください。
SQL Serverでバイト数を取得
DATALENGTH(col)。varchar、nvarchar、varbinaryなど、式の保存に使われるバイト数を確認します。
Oracleでバイト数を取得
LENGTHB(col)。LENGTH(col)は文字数、LENGTHB(col)はバイト数として使い分けます。
PostgreSQLでバイト数を取得
octet_length(col)。length(col)は文字数、octet_length(col)はバイト数です。
MySQLでバイト数を取得
LENGTH(col)またはOCTET_LENGTH(col)。文字数はCHAR_LENGTH(col)です。
-- SQL Server SELECT DATALENGTH(col) AS byte_count FROM table_name; -- Oracle SELECT LENGTHB(col) AS byte_count FROM table_name; -- PostgreSQL SELECT octet_length(col) AS byte_count FROM table_name; -- MySQL SELECT LENGTH(col) AS byte_count FROM table_name;
文字数とバイト数の違い
文字数は、画面上で何文字あるかを数える考え方です。一方、バイト数はデータを保存・転送するときに何バイト使うかを数えます。たとえばUTF-8では、英数字は多くの場合1バイトですが、日本語は1文字あたり3バイトになることがあります。そのため、ABCとあいうはどちらも3文字でも、バイト数は同じとは限りません。
-- イメージ -- 'ABC' : 3文字、3バイトになりやすい -- 'あいう': 3文字、UTF-8では9バイトになりやすい -- 文字数を見る関数と、バイト数を見る関数を混同しない
入力チェック、CSV出力、外部API連携、固定長ファイル、インデックスキー長の調査では、文字数ではなくバイト数が問題になることがあります。文字数順に並べたい場合は 文字数をカウントして多い順・少ない順でソートする方法 のように文字数系の関数を使い、保存サイズや転送サイズを見たい場合はこの記事のバイト数系の関数を使います。
RDBMS別のバイト数取得関数
SQL Server
DATALENGTH(expression) を使います。文字列だけでなく、式が使うバイト数を返すため、varcharとnvarcharで結果が変わる点に注意します。
Oracle
LENGTHB(char) を使います。LENGTHは文字数、LENGTHBはバイト数です。CLOB/NCLOBでは制限があるため、大きなLOBは別の扱いが必要です。
PostgreSQL
octet_length(text) を使います。lengthやchar_lengthは文字数、octet_lengthはバイト数です。
MySQL
LENGTH(str) がバイト数を返します。OCTET_LENGTH(str) は LENGTH の別名です。文字数を取りたい場合は CHAR_LENGTH を使います。
SQL Server: DATALENGTHでバイト数を取得する
SQL Serverでバイト数を取得するなら DATALENGTH を使います。LENは文字数寄りの確認に使われますが、末尾スペースの扱いなども含めてDATALENGTHとは目的が異なります。
SELECT
name,
LEN(name) AS char_count,
DATALENGTH(name) AS byte_count
FROM dbo.customer;
varcharとnvarcharでは同じ文字でも必要なバイト数が変わります。列に関数をかけた条件はインデックス利用に影響することがあるため、大量データで常時検索するなら設計段階で注意してください。関数をWHERE句に書いたときの注意点は SQL Serverでインデックスが使われない原因 も参考になります。
-- 10バイトを超えるデータを調べる SELECT id, name, DATALENGTH(name) AS byte_count FROM dbo.customer WHERE DATALENGTH(name) > 10;
Oracle: LENGTHBでバイト数を取得する
Oracleでは、文字数ならLENGTH、バイト数ならLENGTHBを使います。日本語を含む列で、外部連携の上限や固定長ファイルのサイズを確認したい場合はLENGTHBが向いています。Oracleの文字列関数全体を確認したい場合は Oracle文字列関数完全ガイド も参考にしてください。
SELECT
customer_name,
LENGTH(customer_name) AS char_count,
LENGTHB(customer_name) AS byte_count
FROM customers;
-- 30バイトを超える名前を確認する SELECT customer_id, customer_name, LENGTHB(customer_name) AS byte_count FROM customers WHERE LENGTHB(customer_name) > 30;
Oracleの
LENGTHBは、マルチバイト文字セットのCLOB/NCLOBにはそのまま使えない制限があります。CLOBの一部を扱う、DBMS_LOBを使う、保存サイズを別の方法で確認するなど、LOB用の設計に分けて考えます。PostgreSQL: octet_lengthでバイト数を取得する
PostgreSQLでは、文字数はlengthまたはchar_length、バイト数はoctet_lengthです。サーバーエンコーディングがUTF-8の場合、日本語やアクセント付き文字では文字数とバイト数がずれます。
SELECT
title,
length(title) AS char_count,
octet_length(title) AS byte_count
FROM articles;
-- 255バイトを超える可能性がある値を確認する SELECT id, title, octet_length(title) AS byte_count FROM articles WHERE octet_length(title) > 255;
MySQL: LENGTHまたはOCTET_LENGTHでバイト数を取得する
MySQLではLENGTHがバイト数を返します。OCTET_LENGTHはLENGTHの別名です。一方、文字数を知りたい場合はCHAR_LENGTHを使います。ここは他のDBと名前の感覚がずれやすいので注意してください。
SELECT
name,
CHAR_LENGTH(name) AS char_count,
LENGTH(name) AS byte_count,
OCTET_LENGTH(name) AS byte_count_alias
FROM customers;
-- 100バイトを超える値を調べる SELECT id, name, LENGTH(name) AS byte_count FROM customers WHERE LENGTH(name) > 100;
NULLと空文字、末尾スペースの扱い
バイト数チェックでは、NULL、空文字、末尾スペースの扱いも確認しておくと安全です。特にSQL ServerではLENが末尾スペースを数えない一方、DATALENGTHでは保存されているバイト数を確認できます。データ移行や外部連携の事前調査では、この違いが原因で想定より長い値を見落とすことがあります。
-- SQL Serverの例
SELECT
LEN('ABC ') AS len_count,
DATALENGTH('ABC ') AS byte_count;
-- NULLは多くのDBでNULLとして返るため、比較条件ではCOALESCEも検討する
SELECT COALESCE(DATALENGTH(name), 0) AS byte_count
FROM dbo.customer;
入力制限で使うときの注意点
画面で「20文字まで」と表示しているのに、DBや外部システムでは「40バイトまで」という制限になっていることがあります。この場合、ユーザーに見せる制限は文字数、保存や連携で守る制限はバイト数として、両方を確認する設計にすると事故を減らせます。
画面表示・UIの制限
ユーザーには文字数で説明した方が分かりやすいことが多いです。JavaScriptやアプリ側のバリデーションでは文字数を先に見ます。
DB保存・外部連携の制限
固定長ファイル、古い基幹連携、API仕様、インデックスキー長などではバイト数が重要になります。DB側でもバイト数チェックを用意します。
日本語・絵文字を許可する場合
文字数だけで判定すると、保存時や連携時にバイト上限を超えることがあります。扱う文字種とエンコーディングを前提に確認します。
-- 例: 表示上は20文字以内、連携上は60バイト以内を確認する
SELECT id, display_name
FROM users
WHERE /* RDBMS別のバイト数関数に置き換える */
DATALENGTH(display_name) > 60;
WHERE句で常用するときのパフォーマンス注意点
DATALENGTH(col) > 100 や LENGTHB(col) > 100 のように列へ関数をかける条件は、通常のインデックスが効きにくくなる場合があります。調査用SQLなら問題になりにくいですが、業務画面やバッチで頻繁に実行するなら、バイト数を別列に保持する、計算列や関数ベースインデックスを検討する、登録時に制約で弾くなどの設計が必要です。
-- 例: 調査用にはその場で計算する SELECT id, text_value, DATALENGTH(text_value) AS byte_count FROM dbo.messages WHERE DATALENGTH(text_value) > 4000; -- 頻繁に検索するなら、登録時にbyte_count列へ保持する設計も検討する
よくある間違い
LENGTHなら全部同じだと思う
DBによってLENGTHの意味が違います。MySQLではバイト数、PostgreSQLやOracleでは文字数寄りの用途で使われます。
日本語でも文字数だけ見てしまう
日本語や絵文字は複数バイトになるため、外部連携や固定長データでは文字数チェックだけでは不足します。
NVARCHARとVARCHARを同じに扱う
SQL ServerではnvarcharがUnicode文字列として保存されるため、DATALENGTHの結果がvarcharと変わります。
WHERE句の関数呼び出しを常用する
一時調査なら便利ですが、常時検索条件にするならインデックスや計算済み列を含めて設計します。
公式ドキュメント
- Microsoft Learn: DATALENGTH (Transact-SQL)
- Oracle Database SQL Language Reference: LENGTH
- PostgreSQL Documentation: String Functions and Operators
- MySQL 8.0 Reference Manual: String Functions and Operators
まとめ
SQLでバイト数を取得する関数は、DBごとに名前が違います。SQL ServerはDATALENGTH、OracleはLENGTHB、PostgreSQLはoctet_length、MySQLはLENGTHまたはOCTET_LENGTHです。
文字数とバイト数は、英数字だけなら同じように見えることがあります。しかし、日本語・全角記号・絵文字・Unicode文字列を扱う実務では、両者を分けて確認しないと、保存エラー、連携エラー、想定外の切り詰めにつながります。画面表示は文字数、保存サイズや外部連携はバイト数、という役割分担で考えると判断しやすくなります。
