HN 日本語サマリー

← 一覧へ戻る
プログラミング

SQLiteにおける文字列中のNUL文字

Nul Characters in Strings in SQLite (sqlite.org)

38 pointsby basilikum11 コメント

要約

SQLiteでは、データベースに格納される文字列値の中間にNUL文字(ASCII 0x00)を許可していますが、これが予期せぬ動作を引き起こす可能性があります。length()関数やquote()関数は最初のNUL文字までしか処理せず、CLIの.dumpコマンドもNUL文字以降を省略します。NUL文字の混入は推奨されません。

全文翻訳

小さく。速く。信頼できる。そのどれでも選んでください。 ホーム メニュー ドキュメント ダウンロード ライセンス サポート 購入 検索 ドキュメント 検索 変更履歴 文字列中のNUL文字 1. はじめに SQLiteは、データベースに格納される文字列値の中間にNUL文字(ASCII 0x00、Unicode \u0000)を許可します。しかし、文字列内でのNULの使用は、驚くべき動作につながる可能性があります。 length() SQL関数は、最初のNUL文字まで、およびそれより前の文字のみをカウントします。 quote() SQL関数は、最初のNUL文字まで、およびそれより前の文字のみを表示します。 CLIの.dumpコマンドは、生成されるSQL出力において、最初のNUL文字とその後のすべてのテキストを省略します。事実上、CLIはすべてのコンテキストで最初のNUL文字以降のすべてを省略します。 SQLテキスト文字列でのNUL文字の使用は推奨されません。 2. 予期せぬ動作 以下の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; 上記のSELECT文は、以下の出力を示します。 1,'abc',3 (このドキュメントでは、CLIで".mode quote"が設定されていると仮定します。) しかし、以下を実行するとどうなるでしょうか。 SELECT * FROM t1 WHERE b='abc'; すると、行は返されません。SQLiteは、t1.bカラムが実際には7文字の文字列を保持しており、7文字の文字列 'abc'||char(0)||'xyz' は3文字の文字列 'abc' と等しくないことを認識しているため、行は返されません。しかし、CLIの出力が文字列を3文字としか示さないため、ユーザーは容易に混乱する可能性があります。これはバグのように見えます。しかし、これがSQLiteの動作方法です。 3. 文字列にNUL文字が含まれているかどうかを確認する方法 文字列をBLOBにCASTすると、文字列全体の長さが表示されます。例えば: SELECT a, CAST(b AS BLOB) FROM t1; この結果が得られます。 1,X'6162630078797a' BLOB出力では、7文字の文字列の4番目の文字としてNUL文字をはっきりと見ることができます。 文字列値Xに埋め込まれたNUL文字が含まれているかどうかを判断する、より自動化された方法は、次のような式を使用することです。 instr(X,char(0)) この式がゼロ以外の値Nを返す場合、N番目の文字位置に埋め込まれたNULが存在します。したがって、埋め込まれたNUL文字を含む行数をカウントするには: SELECT count(*) FROM t1 WHERE instr(b,char(0))>0; 4. テキストフィールドからNUL文字を削除する 以下の例は、テーブルのカラムからNUL文字とその後のすべてのテキストを削除する方法を示しています。したがって、埋め込まれたNULを含むデータベースファイルがあり、それらを削除したい場合は、次のようなUPDATEステートメントを実行すると役立つかもしれません。 UPDATE t1 SET b=substr(b,1,instr(b,char(0))) WHERE instr(b,char(0)); このページは2022-05-23 22:21:54Zに最後に更新されました。