2009-08-20 117 views
0

我遇到了一個我尚未解釋的問題。我的代碼需要一個數字,使用NCHR獲取數字的國家代碼,然後對其執行RAWTOHEX轉換。10g和11g差異對Oracle Unicode支持

它在10g多年工作。當我們升級到11g時,它開始返回不同的值。我煮了這一切幾個語句,並創建了一個演示腳本:

SET SERVEROUTPUT ON; 
DECLARE 
    rawVar RAW(2000); 
    nVar NVARCHAR2(1000); 
BEGIN 
    nVar := NCHR(1112); 
    SELECT RAWTOHEX(nVar) INTO rawVar FROM DUAL; 
    DBMS_OUTPUT.PUT_LINE('rawVar: ' || rawVar); 
END; 
/

當在10g中執行時,ouptut是「0458」。在11g(來自同一臺計算機並使用相同的Oracle客戶端軟件)中,輸出爲「00040058」。依賴於輸出的上游過程期望「0458」。有趣的是(對我而言),如果我將nVar的定義更改爲VARCHAR2而不是NVARCHAR2,則在11g上輸出「0458」作爲輸出。

有人可以幫忙解釋爲什麼結果不同嗎?我已經搜索了Oracle的發行說明和支持系統,但沒有找到任何答案。

非常感謝提前。

+0

您可以從SQL環境運行此操作:select nchr(1112)nchr,rawtohex(nchr(1112))rth from dual; – dpbradley 2009-08-20 17:15:16

+0

兩種環境中的營養素相同,NCHR是「?」並且RTH是「0458」 – elmnoise 2009-08-20 17:19:36

+0

因此,似乎dbms_output中的varchar轉換正在影響該值 - 這與您的上游進程如何接收該值類似? – dpbradley 2009-08-20 19:34:25

回答

0

這兩個數據庫是否使用相同的字符集?

你能在這兩種情況下運行此查詢:

select value 
    from nls_database_parameters 
where parameter='NLS_NCHAR_CHARACTERSET'; 

CHR和NCHR功能只會產生相同的結果,如果數據庫具有相同的字符集。

+0

感謝您的快速回復。是的,他們都是「AL16UTF16」。 – elmnoise 2009-08-20 17:04:12

0

RAWTOHEX返回一個字符值,但是您將其選中到RAW中,因此會出現一些隱式轉換。然後你試圖使用DBMS_OUTPUT,它需要隱式地將該RAW變量轉換爲一個字符串。

可能可以處理原始值(即字節)或字符值(可能會根據字符集/語言設置進行轉換/翻譯的文本)或字符串中字節的十六進制表示。你在數據庫中擁有哪些數據庫?你想要返回哪個應用程序?然後,只需執行一次轉換並明確執行。

+0

謝謝。我明白這個方法不是很理性。不過,我的問題是爲什麼相同的代碼在Oracle 10g和Oracle 11g中返回不同的值。 – elmnoise 2009-08-24 14:20:37

+0

我懷疑在RAW中將內容轉換爲多字節字符集中的VARCHAR時發生了某些變化,但沒有數據庫可用於測試該假設。 – 2009-08-24 22:32:21

1

這是Oracle 11 變化

nVar := NCHR(1112); 

一個可怕的錯誤,以

nVar := CHR(1112 using nchar_cs); 

事情會再次合作。根據Oracle文檔,這些表達式應該完全相同。在Oracle 10中,這是真實的,但不是11.