Символы NUL в строках
1. Введение
SQLite допускает использование символов NUL (ASCII 0x00, Unicode \u0000) в середине строковых значений, хранящихся в базе данных. Однако использование NUL внутри строк может привести к неожиданному поведению:
Функция length() SQL считает только символы до первого символа NUL, не включая его.
Функция quote() SQL отображает только символы до первого символа NUL, не включая его.
Команда .dump в CLI опускает первый символ NUL и все последующие символы в выводе SQL, который она генерирует. Фактически, CLI опускает все после первого символа NUL во всех контекстах.
Использование символов NUL в строках SQL не рекомендуется.
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 символов, а строка 'abc'||char(0)||'xyz' длиной 7 символов не равна строке 'abc' длиной 3 символа, и поэтому строки не возвращаются. Однако пользователь может легко запутаться, так как вывод CLI показывает, что строка содержит только 3 символа. Это кажется ошибкой. Но это то, как работает SQLite.
3. Как определить, есть ли символы NUL в ваших строках
Если вы преобразуете строку в BLOB, то показывается вся длина строки. Например:
SELECT a, CAST(b AS BLOB) FROM t1;
Это дает следующий результат:
1,X'6162630078797a'
В выводе BLOB вы можете четко увидеть символ NUL как 4-й символ в строке длиной 7 символов.
Другой, более автоматизированный способ определить, содержит ли строковое значение X вложенные символы NUL, заключается в использовании выражения такого типа:
instr(X,char(0))
Если это выражение возвращает ненулевое значение N, то вложенный символ NUL существует в позиции N-го символа. Таким образом, для подсчета количества строк, содержащих вложенные символы 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));
Эта страница была обновлена 23 мая 2022 г. 22:21:54 UTC
SQLite is in the Public Domain.
https://sqlite.org/nulinstr.html