2010-06-07 96 views
1

我在PostgreSQL中使用bytea类型,据我了解,它只包含一系列字节。但是,我无法让它与空值打好。例如:bytea类型和空值,Postgres

=# select length(E'aa\x00aa'::bytea); 
length 
-------- 
     2 
(1 row) 

我期待5.另外:

=# select md5(E'aa\x00aa'::bytea); 
       md5 
---------------------------------- 
4124bc0a9335c27f086f24ba207a4912 
(1 row) 

这就是 “AA” 的MD5,而不是 “AA \ x00aa”。显然,我做错了,但我不知道我做错了什么。由于我无法控制的原因,我也在使用旧版Postgres(8.1.11)。 (我会看看这个,只要我回家的行为最新的Postgres一样...)

+1

8.4在尝试为我构建字符串(在转换为bytea之前)时抱怨无效编码。 – araqnid 2010-06-07 18:30:44

回答

8

试试这个:

# select length(E'aa\\000aa'::bytea); 
length 
-------- 
     5 

更新:为什么原来没有工作?首先,要明白一个斜线和两者之间的区别:

pg=# select E'aa\055aa', length(E'aa\055aa') ; 
?column? | length 
----------+-------- 
aa-aa |  5 
(1 row) 

pg=# select E'aa\\055aa', length(E'aa\\055aa') ; 
?column? | length 
----------+-------- 
aa\055aa |  8 

在第一种情况下,我在写文字字符串,4个字符转义(“a”)和一个逃脱。语法分析器在第一遍中使用斜杠,它将完整的\055 转换为单个字符(在这种情况下为' - ')。

在第二种情况下,第一个斜杠恰好跳过第二个,解析器将该对\\翻译为单个\,并将055看作三个字符。

现在,在将文本转换为bytea时,转义字符(在已解析或生成的文本中)将被解析/解释为again! (是的,这是令人困惑的)。

所以,当我写

select E'aa\000aa'::bytea; 
在第一解析

,字面E'aa \ 000aa”在第三位置转换为内部文本以空字符(并根据您的PostgreSQL版本,空字符被解释为EOS,并且文本被假定为长度为2的文本 - 或者在其他版本中引发非法字符串错误)。

相反,当我写

select E'aa\\000aa'::bytea; 
在第一解析

,文字串 “AA \ 000aa”(8个字符)所看到的,并且被asigned到文本;然后在转换为bytea时再次解析,并将字符'\ 000'的序列解释为空字节。

IMO postgresql在这里很糟糕。

+0

好的。现在为什么这个工作? – Thanatos 2010-06-07 18:50:38

+0

啊 - 我想我看到:Postgres字符串不能表示二进制数据,所以他们使用一个转义形式,其中null是\ 000,我们必须输入'\\ 000'。我现在看到PQescapeBytea和PQunescapeBytea--我假设如果我选择一个bytea列,我会得到这个中间转义形式,然后我必须通过PQunescapeBytea。这一切现在更有意义。 – Thanatos 2010-06-07 19:18:09

+0

是的,谢谢你的更新。这证实了我的想法,以及你在哪里标注了“(是的,这是令人困惑的)。”我完全同意! – Thanatos 2010-06-07 19:42:54

相关问题