SQLite の文字列中のゼロ改行文字 (Null Character)

2026/07/16 8:03

SQLite の文字列中のゼロ改行文字 (Null Character)

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

SQLite はテキストカラム内に埋め込まれた NUL 文字(ASCII 0x00)を許可していますが、その使用は推奨されていません。SQLite の内部関数は、そのようなデータを最初の NUL までの文字列として扱い、

length()
および
quote()
はその点までの字符数を数え/表示し、CLI 上の
.dump
コマンド(
.mode quote
が設定されていると仮定)は最初の NUL 以降のすべてを省略します。その結果、
SELECT * FROM t1 WHERE b='abc'
といった検索では、カラムの値が
'abc'||char(0)||'xyz'
で、実際に 7 文字保持されていても、行が返却されないことがあります。SQLite は完全な長さを知っていますが、CLI の出力や一部の関数は、ユーザーに文字列が早期で終わっていると誤認させる可能性があります。真の内容を確認するには、カラムを BLOB にキャストします(例:
CAST(b AS BLOB)
)。埋め込まれた NUL を検出するには、
instr(X, char(0))
を使用し、これが最初の NUL の位置を返すか、存在しない場合は 0 を返します。NUL を含む行を特定するには、
SELECT count(*) FROM t1 WHERE instr(b,char(0))>0
を使用します。必要であれば、
UPDATE t1 SET b=substr(b,1,instr(b,char(0))) WHERE instr(b,char(0));
で NUL とその後のすべての文字列を削除できます。これらの手順は、沈黙するロジックエラーを防ぎ、本番環境での信頼性の高いテキスト処理を保証します。(コンテンツは 2022-05-23 に最終更新)

本文

SQLite で NUL 文字を使用した場合の注意点

はじめに

SQLite では、データベースに格納された文字列値の中央部においても NUL 文字(ASCII

0x00
または Unicode
\u0000
)を使用 technically できます。しかし、以下の通り予期せぬ動作を引き起こす可能性があります。

  • length()
    関数
    : 最初の NUL 文字までのみカウントし、それ以降を含みません。
  • quote()
    関数
    : 同様に、最初の NUL 文字までの部分のみを表示します(以降は非表示)。
  • CLI の
    .dump
    コマンド
    : 生成される SQL 出力で、最初の NUL 文字以降のテキストをすべて省略します。

したがって、SQL テキスト文字列に NUL 文字を含めることは推奨されません


予期せぬ動作の具体例

以下の SQL スクリプトを考慮してください。

CREATE TABLE t1(
  a INTEGER PRIMARY KEY,
  b TEXT
);
INSERT INTO t1(a,b) VALUES(1, 'abc'||char(0)||'xyz');
SELECT a, b, length(b) FROM t1;

出力結果の特性:

  • データベースには実際には
    7
    文字(
    'abc'
    + NUL +
    'xyz'
    )が格納されています。
  • しかし、CLI の表示上は NUL 文字より前の部分(
    'abc'
    )のみの
    3
    文字として表示されます。
  • length(b)
    も最初の NUL 文字までのみカウントするため
    3
    を返します。

クエリ検索による挙動:

SELECT * FROM t1 WHERE b='abc';
  • 結果: 該当する行は一つも返されません。
  • 理由: SQLite は列に
    'abc'
    と等しくない
    7
    文字のデータを格納しているため、一致しません。
  • 影響: ユーザーが表示されるテキスト(
    3
    文字)と実際の内容(
    7
    文字)に混乱し、「バグではないか」と誤解する可能性があります。

NUL 文字の検出方法

1. BLOB 型へ CAST する

文字列を

BLOB
型に変換すると、NUL 文字が正確な位置(第 4 文字)として表示されます。

SELECT a, CAST(b AS BLOB) FROM t1;

2. インデックス関数を使う

特定の文字列が含まれているかどうかを確認する式を作成できます。以下は NUL 文字が埋め込まれている行を検出する例です。

-- 第 4 文字位置に NUL 文字がある場合の検証
SELECT instr(b, char(0)) FROM t1; 
-- 結果:0(発見しない), 4(第 4 文字で発見)など(非ゼロ=発見)

埋め込まれた NUL 文字を含む行の数を数えるには、以下を実行します。

SELECT count(*) FROM t1 WHERE instr(b,char(0)) > 0;

テキストフィールドから NUL 文字を取り除く方法

テーブルのコラムに NUL 文字が含まれている場合、その以降のテキストも取り除く必要があります。データベースファイルからこれらの不具合を修正したい場合は、以下の

UPDATE
ステートメントを実行してください。

-- NUL 文字までの文字列のみを残し、以降を削除する
UPDATE t1 
SET b = substr(b, 1, instr(b, char(0))) 
WHERE instr(b, char(0));

注意点: この操作はデータを破損させるため、バックアップを取ってから実行してください。

同じ日のほかのニュース

一覧に戻る →