2010-02-24 6 views
11

Ich habe eine Abfrage, die zwei Tabellen verbindet. Eine Tabelle hat eine Spalte vom Typ varchar und die andere Tabelle hat einen Nummerntyp. Ich habe meine Abfrage in 3 Oracle-Datenbanken ausgeführt und sehe einige seltsame Ergebnisse, von denen ich hoffe, dass sie erklärt werden können. Auf zwei der Datenbanken funktioniert so etwas wie das Folgende.Oracle-Nummer und Varchar Join

select a.col1, b.somecol 
from tableA a inner join tableB b on b.col2=a.col1; 

In dieser Abfrage tableA.col1 ist die Typennummer und tableB.col2 ist vom Typ varchar. Dies funktioniert in zwei der Datenbanken, aber nicht in der dritten. Im dritten bekomme ich (ORA-01722) einen Fehler. In der dritten muss ich etwas tun wie ...

select a.col1, b.somecol 
from tableA a inner join tableB b on b.col2=to_char(a.col1); 

Dies funktioniert in allen Datenbanken. Die Frage, die ich habe, ist warum? Das obige ist eine vereinfachte Abfrage, und die echte Abfrage ist ein wenig komplexer und ruft eine Menge Daten ab, daher ist die erste Version viel schneller. Wenn ich es schaffen würde, in allen Umgebungen zu arbeiten, wäre es großartig.

Weiß jemand, warum dies in einigen Oracle-Datenbanken und nicht in anderen ohne die Besetzung des Datentyps funktioniert? Gibt es eine globale Einstellung, die ein solches Verhalten ermöglicht?

+1

Sortierungs meine erste Vermutung sein. Oracle erlaubt normalerweise implizite Konvertierung, also könnte es sein, dass eine Spalte keine implizite Konvertierung durchführt ... –

+1

Sie haben all diese Wörter geschrieben und es gelang Ihnen immer noch nicht genau zu erklären * wie * die erste Abfrage nicht funktioniert dritte Datenbank. – APC

+0

Sorry, bekomme ich einen ORA-01722 Fehler in der ersten Abfrage, dritte Datenbank – broschb

Antwort

15

Ein Grund, warum implizite Konvertierungen fehlschlagen, ist, wenn die verknüpfende varchar-Spalte Daten enthält, die nicht numerisch sind. Oracle übernimmt Nummer varchar2 schließt sich durch die Saiten Umwandlung (check out Garys Zitat in seinem Kommentar), so führt er eigentlich diese:

select a.col1, b.somecol 
from tableA a inner join tableB b on to_number(b.col2)=a.col1; 

Wenn tableB.col2 Werte enthält, die nicht numerisch sind - sehr wahrscheinlich scheint, ist es eine Schnur schließlich - dann wird es ORA-01722: invalid number schleudern. Wenn Sie die Zahlenspalte explizit in eine Zeichenfolge umwandeln, schließen Sie das Standardverhalten von Oracle kurz.

Die Tatsache, dass Sie dieses Problem in Ihren ersten beiden Umgebungen nicht bekommen, ist Glückssache, keine Konfiguration. Es kann jederzeit auftreten, da nur eine nicht numerische Zeichenfolge erforderlich ist, um die Abfrage zu unterbrechen. Du solltest also mit der expliziten Konvertierung in allen Umgebungen arbeiten.

Was die Leistung, eine Funktion basierten Index ... bauen könnte, würde

create index whatever_idx on tableA (to_char(col1)) 
/
+2

Ein bisschen nach http://download.oracle.com/docs/cd/B19306_01/server.102/b14200 /sql_elements002.htm#r16c1-t41 "Beim Vergleichen eines Zeichenwerts mit einem numerischen Wert konvertiert Oracle die Zeichendaten in einen numerischen Wert." –

+0

Sie können die Zahl in TabelleA stattdessen in eine Zeichenfolge umwandeln, sodass Sie keine Fehler erhalten, wenn in TabelleB eine nicht numerische Zeichenfolge vorhanden ist. dh CAST (a.col1 AS VARCHAR (20)) –