2008-10-30 33 views
30

我有一个包含BLOB文件的sqlite表,但需要对blob进行大小/长度检查,我该怎么做?如何在sqlite中找到二进制blob的长度(大小)

根据我找到的一些文档,使用长度(blob)将不起作用,因为length()仅适用于文本,并会在第一个NULL之后停止计数。我的实证检验显示这是真实的。

我使用SQLite 3.4.2


更新:

那么作为的SQLite 3.7.6看起来好像长度()函数返回的斑点正确的价值 - 我查sqlite的各种更改日志,但没有看到该版本已更正。

从SQLite的3.7.6:

 
payload_id|length(payload)|length(hex(payload))/2 
1807913|194|194 
1807914|171|171 

documentation改为反映这一点。

 
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. 

回答

35

都没有这个问题,但你可以尝试length(hex(glob))/2

更新(AUG-2012): SQLite的3.7.6(发布2011年4月12日),后来,length(blob_column)作品正如预期的那样,文本和二进制数据。

9

对我来说length(blob)工作得很好,给出了与其他结果相同的结果。

+2

对于二进制blob?这将违反SQLite文档,它将blob视为文本,并且只有在找到'\ 0`字符之前length()才是准确的。 – Petriborg 2010-09-24 10:55:00

3

一个select查询执行此,获得在myblob柱团块的长度,在表mytable,在第3行的实施例:

select length(myblob) from mytable where rowid=3; 
2

LENGTH()函数源码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 
6

作为一个附加的应答,一个常见的问题是源码有效地忽略表的列类型,因此,如果你存储一个字符串BLOB列,成为该行一个字符串列。由于字符串的长度不同,它只会返回最后0个八位字节前的字符数。这很容易在BLOB列存储字符串,因为你通常需要显式强制插入一个blob:

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 

长度(十六进制(blob-column))/ 2工作的原因是十六进制不会停止在内部0字节,并且生成的十六进制字符串不再包含0八位字节,所以长度返回正确的总长度。

一个字符存储在一个字节中,可以表示为2个十六进制字符串。