![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
SQLite позволяет символы NUL (ASCII 0x00, Unicode \u0000)
посреди значений последовательности, сохраненных в базе данных.
Однако, использование NUL в последовательностях может
привести к удивительным поведениям: SQL-функция length()
считает знаки только до NUL, исключая первый символ NUL. SQL-функция quote()
показывает знаки только до NUL, исключая первый символ NUL. Команда .dump в
CLI опускает первый символ NUL
и весь последующий текст в выводе SQL, которую это производит. На самом деле
CLI опускает все после первого символа NUL
во всех контекстах. Использование знаков NUL в последовательностях кода на
SQL не рекомендуется. Рассмотрите следующий SQL: Оператор SELECT выше выведет: Здесь мы предполагаем, что CLI использует
".mode quote". Но если вы выполните: Тогда никакие строки не возвращены. SQLite знает, что колонка t1.b на
самом деле содержит 7-символьную строку и 7-символьная строка
'abc'||char(0)||'xyz' не равна 3-символьной строке 'abc', и таким образом
никакие строки не возвращены. Но пользователь мог бы быть легко смущен этим,
потому что вывод CLI
показывает, что у последовательности есть только 3 знака.
Это походит на ошибку. Но это как SQLite работает. Если вы CAST строку в BLOB,
то всю длину последовательности показывают. Например: Дает этот результат: В выводе BLOB можно ясно рассмотреть символ NUL как 4-й символ в
7-символьной строке. Другой, более автоматизированный, способ сказать, содержит ли
значение последовательности X включенные знаки NUL, должен
использовать такое выражение, как это: Если это выражение возвращает ненулевое значение N, то там существует
вложенный NUL в позиции N. Таким образом, чтобы посчитать количество строк,
которые содержат включенные знаки NUL: Следующий пример показывает, как удалить
NUL и весь текст, который следует за ним, из колонки таблицы.
Таким образом, если у вас есть файл базы данных, который содержит включенный
NUL, и требуется удалить его, управлять UPDATE, подобным следующему:
Choose any three.
1. Введение
2. Неожиданное поведение
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;
1,'abc',3
SELECT * FROM t1 WHERE b='abc';
3. Как сказать, есть ли у вас знаки NUL в последовательностях
SELECT a, CAST(b AS BLOB) FROM t1;
1,X'6162630078797a'
instr(X,char(0))
SELECT count(*) FROM t1 WHERE instr(b,char(0))>0;
4. Удаление знаков NUL из текстового поля
UPDATE t1 SET b=substr(b,1,instr(b,char(0))) WHERE instr(b,char(0));