2015-12-02 44 views
0

我目前正在開始將應用程序的postgres 8.4 db升級到9.4的過程。實際的數據庫遷移已經完美無缺,但有些應用程序查詢在針對9.4數據庫運行時不會返回奇怪的結果。我爲C#使用NpgSql v2.0.12.0庫。這個問題似乎與存儲以base64字符串編碼的文本數據的幾個表相關。查詢調用postgres解碼函數,以便將編碼數據作爲純文本返回。例如:NpgSql - 從具有解碼功能的查詢返回的錯誤數據

SELECT 
    decode(user_name, 'base64')::text as user_name 
    FROM 
    login 
    WHERE 
    login_id = 123; 

提交到8.4 DB時,字符串被正確地返回到應用程序。當提交到9.4 DB我得到

\x61646d696e6973747261746f72 

在pgAdmin的SQL工具的結果是在這兩種情況下是正確的。我確信這可能是某種編碼問題,但對於我來說我無法弄清楚 - 我已經搜索了好幾個小時,通過postgres文檔挖掘並在這裏無休止地搜索,最終未能找到解決我的問題。希望有一些PostGres的人可以指出我正確的方向來解決這個問題。

+0

什麼是「正確」?顯示你認爲它*應該*也是。猜測你遇到了默認的'bytea_output'設置更改的問題。 –

+0

在這種情況下,正確的響應應該是「管理員」。 – kdavej

+0

Npgsql 2.0.12絕對是古老的...你絕對應該嘗試升級到最新的3.x –

回答

1

你一直依靠在當前編碼中將bytea輸出解釋爲一個字符串,也就是說,你的代碼一直是錯誤的,但碰巧有效。

較舊的PostgreSQL版本對bytea文字使用「轉義」格式,對於7位ASCII字符看起來像純文本,對於非打印字符和8位字符使用八進制轉義。

test=> SET bytea_output = 'escape'; 
SET 
test=> SELECT convert_to('administrator á 
', 'utf-8'); 
     convert_to   
---------------------------- 
administrator \303\241\012 
(1 row) 

後來的Pos​​tgreSQL版本默認爲「十六進制」輸出,編碼一切爲十六進制:

test=> SET bytea_output = 'hex'; 
SET 
test=> SELECT convert_to('administrator á 
', 'utf-8'); 
       convert_to    
-------------------------------------- 
\x61646d696e6973747261746f7220c3a10a 
(1 row) 

讓你的應用程序無法逃脫假設BYTEA是文本了。

如果base64字符串是當前本地文本編碼中的有效文本,則可以使用convert_from(decode(user_name, 'base64'), 'utf-8')。但在這種情況下,您應該將其存儲爲正常的text而不是base64編碼的。

如果base64字符串是而不是在當前編碼中有效,例如,它包含空字節,無法在client_encoding等中表示的字符,那麼您應該返回十六進制或base64表示並在客戶端應用程序中對其進行解碼。

+0

謝謝!這是遺留系統,更新應用程序中的每個查詢都不會是一個好場景。我能夠將服務器配置爲恢復舊的「轉義」格式,以便在我們制定更好的整體解決方案時保持我們的狀態。 – kdavej