2009-08-20 11 views
0

Ich stoße auf ein Problem, das ich noch nicht erklären konnte. Ich habe Code, der eine Nummer nimmt, den nationalen Zeichencode für die Nummer mit NCHR erhält und dann eine RAWTOHEX-Konvertierung durchführt.Oracle Unicode-Unterstützung in 10g und 11g Unterschiede

Es funktionierte in 10g seit Jahren. Als wir auf 11g aufrüsten, werden verschiedene Werte zurückgegeben. Ich kochte es alle bis auf wenige Aussagen und eine Demonstration Skript erstellt:

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; 
/

Wenn in 10g ausgeführt, die ouptut ist „0458“. In 11g (vom selben Computer und mit derselben Oracle-Client-Software) lautet die Ausgabe "00040058". Der Upstream-Prozess, der auf die Ausgabe angewiesen ist, erwartet "0458".

Interessanterweise (für mich), wenn ich die Definition von nVar zu einem VARCHAR2 anstelle eines NVARCHAR2 ändern, bekomme ich "0458" als Ausgabe auf 11g.

Kann jemand bitte helfen zu erklären, warum die Ergebnisse unterschiedlich sind? Ich habe Oracle Release Notes und Support-System durchsucht, aber keine Antworten gefunden.

Vielen Dank im Voraus.

+0

könnten Sie dies aus einer SQL-Umgebung ausführen: Wählen Sie nchr (1112) nchr, raltohex (nchr (1112)) rth aus Dual; – dpbradley

+0

Beide Umgebungen sreutrn das gleiche, NCHR ist "?" und RTH ist "0458" – elmnoise

+0

So scheint es, dass die Konvertierung in Varchar in der dbms_output den Wert beeinflusst - ist das ähnlich, wie Ihr Upstream-Prozess den Wert erhält? – dpbradley

Antwort

0

Verwenden die beiden Datenbanken den gleichen Zeichensatz?

Könnten Sie diese Abfrage in beiden Fällen laufen:

select value 
    from nls_database_parameters 
where parameter='NLS_NCHAR_CHARACTERSET'; 

CHR und NCHR Funktionen wird nur das gleiche Ergebnis, wenn die Datenbanken denselben Zeichensatz haben.

+0

Danke für die schnelle Antwort. Ja, sie sind beide "AL16UTF16". – elmnoise

0

RAWTOHEX gibt einen Zeichenwert zurück, aber Sie wählen ihn in ein RAW, so dass dort eine implizite Konvertierung stattfindet. Dann versuchen Sie, DBMS_OUTPUT zu verwenden, das diese RAW-Variable implizit in eine Zeichenfolge konvertieren muss.

Möglicherweise können Sie mit einem RAW-Wert (dh Bytes) oder einem Zeichenwert (Text, der abhängig von Zeichensatz/Spracheinstellungen konvertiert/übersetzt werden kann) oder einer hexadezimalen Darstellung der Bytes in der Zeichenkette umgehen. Welche davon haben Sie in der Datenbank und welche möchten Sie an die Anwendung zurückgeben? Dann mach einfach diese EINE Konvertierung und mache es explizit.

+0

Danke.Ich verstehe, dass die Methode nicht sehr vernünftig ist. Wie auch immer, meine Frage ist, warum der gleiche Code unterschiedliche Werte in Oracle 10g vs. Oracle 11g zurückgibt. – elmnoise

+0

Ich vermute, dass sich etwas in der impliziten Konvertierung von RAW in VARCHAR in Multi-Byte-Zeichensätzen geändert hat, aber keine Datenbanken zur Verfügung haben, um die Annahme zu testen. –

1

Dies ist ein schrecklicher Fehler in Oracle 11 ändern

nVar := NCHR(1112); 

zu

nVar := CHR(1112 using nchar_cs); 

und die Dinge werden wieder funktionieren. Diese Ausdrücke sollten laut Oracle-Dokumenten identisch sein. In Oracle 10 ist dies richtig, aber nicht in 11.