Как мне найти длину (размер) двоичного объекта в sqlite
Вопрос
У меня есть таблица sqlite, содержащая BLOB-файл, но мне нужно проверить размер/длину BLOB-объекта. Как мне это сделать?
Согласно некоторой документации, которую я нашел, использование length(blob) не будет работать, поскольку length() работает только с текстами и перестанет считать после первого NULL.Мои эмпирические тесты показали, что это правда.
Я использую SQLite 3.4.2
Обновления:
Итак, начиная с SQLite 3.7.6, похоже, что функция length() возвращает правильное значение больших двоичных объектов - я проверил различные журналы изменений sqlite, но не увидел, в какой версии это было исправлено.
Из Sqlite 3.7.6:
payload_id|length(payload)|length(hex(payload))/2 1807913|194|194 1807914|171|171
А документация был изменен, чтобы отразить это.
length(X) The length(X) function returns the length of X in characters if X is a string, or in bytes if X is a blob. If X is NULL then length(X) is NULL. If X is numeric then length(X) returns the length of a string representation of X.
Решение
у меня не было такой проблемы, но можно попробовать length(hex(glob))/2
Обновление (август 2012 г.):Для SQLite 3.7.6 (выпущенной 12 апреля 2011 г.) и более поздних версий: length(blob_column)
работает как положено как с текстовыми, так и с двоичными данными.
Другие советы
для меня length(blob)
работает нормально, дает те же результаты, что и другой.
В качестве дополнительного ответа: распространенная проблема заключается в том, что sqlite фактически игнорирует тип столбца таблицы, поэтому, если вы сохраняете строку в столбце blob, она становится строковый столбец для этой строки.Поскольку длина работает со строками по-разному, тогда она вернет только количество символов до последнего 0 октета.Хранить строки в столбцах больших двоичных объектов легко, поскольку для вставки большого двоичного объекта обычно требуется явное приведение типов:
insert into table values ('xxxx'); // string insert
insert into table values(cast('xxxx' as blob)); // blob insert
чтобы получить правильную длину значений, хранящихся в виде строки, вы можете привести аргумент длины к BLOB-объекту:
select length(string-value-from-blob-column); // treast blob column as string
select length(cast(blob-column as blob)); // correctly returns blob length
Причина, по которой работает length(hex(blob-column))/2, заключается в том, что hex не останавливается на внутренних 0 октетах, а сгенерированная шестнадцатеричная строка больше не содержит 0 октетов, поэтому length возвращает правильную (полную) длину.
Пример select
запрос, который делает это, получая длину большого двоичного объекта в столбце myblob
, в таблице mytable
, в строке 3:
select length(myblob) from mytable where rowid=3;
Функция LENGTH() в sqlite 3.7.13 в Debian 7 не работает, но LENGTH(HEX())/2 работает нормально.
# sqlite --version
3.7.13 2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc
# sqlite xxx.db "SELECT docid, LENGTH(doccontent), LENGTH(HEX(doccontent))/2 AS b FROM cr_doc LIMIT 10;"
1|6|77824
2|5|176251
3|5|176251
4|6|39936
5|6|43520
6|494|101447
7|6|41472
8|6|61440
9|6|41984
10|6|41472