2010-06-07 100 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

相關問題