🐥

SQL Serverで文字列長を正しく数える

に公開

SQL Server で文字列の長さを数えるとき、LENDATALENGTH では挙動が違います。
この記事ではそれぞれの違いと絵文字など補助文字を含めた正しい数え方を解説します。

LEN の仕様

LEN文字数を返します。ただし 末尾の空白は無視します。

SELECT LEN(N'ABCD  '); -- 4  ← 末尾2つの空白は無視

DATALENGTH の仕様

  • DATALENGTHバイト数 を返します。
  • NVARCHAR なら 1コードユニットが2バイトなので /2 すれば「UTF-16 コード単位数」を得られる
SELECT DATALENGTH(N'ABCD  ') / 2; -- 6  ← 空白も含めた長さ

注意

varcharDATALENGTH を使うと「バイト数」そのものを返します。

  • 照合順序が UTF-8 なら 1〜4バイト/文字 → /2 は破綻します。
  • NVARCHAR で使う必要があります。

末尾空白を含めて「文字数」を得たい場合

LEN にダミー文字を末尾に追加して1を引く方法がある。

SELECT LEN(N'ABCD  ' + N';') - 1; -- 6

この方法なら末尾空白も正しく数えられる。

サロゲートペア(補助文字)の扱い

SQL Server の NVARCHAR は内部では UTF-16 です。

  • 通常の文字: 2バイト
  • 補助文字(例: 🗿): サロゲートペアで 4バイト

デフォルトでは 🗿 は 2文字 と数えられてしまう。
これを 1文字として数えたい場合は、補助文字 の照合順序 _SC(Supplementary Character-Aware)を使う。

-- デフォルト照合順序
SELECT LEN(N'🗿'); -- 2

-- _SC 照合順序を指定
SELECT LEN(N'🗿' COLLATE Latin1_General_100_CI_AS_SC); -- 1

実務での指針

  • 文字数が欲しい
    • 末尾空白を含めない → LEN(@s COLLATE …_SC)
    • 末尾空白を含める → LEN((@s COLLATE …_SC) + N';') - 1
  • バイト数が欲しい
    • NVARCHAR → DATALENGTH(@s)
    • VARCHAR → DATALENGTH(@s)(1〜4バイト/文字に注意)

まとめ

  • LEN は末尾空白を無視する
  • DATALENGTH はバイト数を返す(NVARCHAR なら /2 でコード単位数)
  • 補助文字を 1 文字扱いするなら照合順序 _SC が必須
  • 実務では「文字数」か「バイト数」かを意識して関数を選ぶ。

Discussion