2009-09-14 6 views
31

Dies ist das erste Mal, dass ich mit Oracle zu tun habe, und es fällt mir schwer zu verstehen, warum ich diesen Fehler erhalte.Oracle "ORA-01008: nicht alle Variablen gebunden" Fehler mit Parametern

Ich verwende Oracle ODT.NET w/C# mit dem folgenden Code in einer Abfrage where-Klausel:

WHERE table.Variable1 = :VarA 
    AND (:VarB IS NULL OR table.Variable2 LIKE '%' || :VarB || '%') 
    AND (:VarC IS NULL OR table.Variable3 LIKE :VarC || '%') 

und ich hinzufüge, die Parameterwerte wie folgt:

cmd.Parameters.Add("VarA", "24"); 
cmd.Parameters.Add("VarB", "test"); 
cmd.Parameters.Add("VarC", "1234"); 

Wenn ich diese Abfrage ausführen, liefert der Server:

ORA-01008: not all variables bound 

Wenn ich einen der Kommentar aus ‚AND (....‘ Zeilen, die Abfrage comp Leitet erfolgreich.

Warum sollte die Abfrage in Ordnung sein, wenn ich nur mit zwei Parametern abfrage, aber nicht mit drei? Der Fehler Ich erhalte auch keinen Sinn

+0

sind aus der SQL-Anweisung drucken Sie in der Lage DBMS_OUTPUT zu verwenden, bevor es ausgeführt wird? –

Antwort

42

Der ODP.Net-Anbieter von Orakel verwendet Bindung von Position als Standard. So ändern Sie das Verhalten zum Binden nach Namen. Setzen Sie die Eigenschaft BindByName auf true. Dann können Sie die Doppeldefinition der Parameter verwerfen.

using(OracleCommand cmd = con.CreateCommand()) { 
    ... 
    cmd.BindByName = true; 
    ... 
} 
+0

das macht mehr Sinn ... Ich habe gestern die Parameter neu angeordnet und festgestellt, dass es durch die Position der Variablen und nicht den Namen verbindlich war (was nicht gut war); wusste nicht, dass es eine Option gab, das zu ändern – John

+0

Das ist gut Christian13467! Ich wusste das also nicht meine Erfahrung mit dem nativen .Net Oracle Data Provider von 8i bis 10g. Danke für diese Antwort. –

+1

Ausgezeichnete Lösung. Viel besser als das Duplizieren der Parameter. @John - du solltest wirklich in Betracht ziehen, diese Antwort zu akzeptieren, wenn ich darf - über 13000 Leute haben deine Frage schon gesehen, sie hätten zuerst die bessere Option sehen sollen.(Sorry Tony) – Kobi

23

Es scheint, bekloppt, aber ich denke, wenn Sie die gleiche Bindevariable verwenden zweimal Sie es zweimal einstellen:

cmd.Parameters.Add("VarA", "24"); 
cmd.Parameters.Add("VarB", "test"); 
cmd.Parameters.Add("VarB", "test"); 
cmd.Parameters.Add("VarC", "1234"); 
cmd.Parameters.Add("VarC", "1234"); 

Sicherlich das stimmt mit der gebürtigen Dynamischer SQL in PL/SQL:

SQL> begin 
    2  execute immediate 'select * from emp where ename=:name and ename=:name' 
    3  using 'KING'; 
    4 end; 
    5/
begin 
* 
ERROR at line 1: 
ORA-01008: not all variables bound 


SQL> begin 
    2  execute immediate 'select * from emp where ename=:name and ename=:name' 
    3  using 'KING', 'KING'; 
    4 end; 
    5/

PL/SQL procedure successfully completed. 
+0

Das hat funktioniert ... kann nicht glauben, dass es in diesem Herrenhaus funktionieren würde, aber es hat funktioniert, also nehme ich es! Vielen Dank! – John

+1

Sie müssen nicht nur mehrmals angegeben werden, sondern sie müssen in der Reihenfolge hinzugefügt werden, in der sie in der Abfrage erscheinen. –

+0

Ich will nicht auf einen sehr alten Post huckepack ... aber weiß jemand, ob dies (immer noch mehrere Parameter hinzufügen, wenn mehrmals verwendet) immer noch der Fall ist? Ich habe es mit einem seltsamen Szenario zu tun, bei dem etwas lokal für mich funktioniert, aber es ist fehlgeschlagen, als es von einem Benutzer in der Produktion ausgeführt wurde. Hat die Änderung für den Moment zurückgesetzt, aber etwas ratlos, warum der '01008' Fehler nur dem Benutzer aufgefallen ist. –

2

Sie auch die Notwendigkeit von duplizierten Parameternamen in der SQL-Entfernung betrachten könnte Ihre Sql zu

table.Variable2 LIKE '%' || :VarB || '%' 

und dann Ihr Kunde immer zur Verfügung zu stellen ‚%‘ für jeden Wert von VARB durch Änderung statt Null. In gewisser Hinsicht denke ich, dass dies natürlicher ist.

Sie könnten auch die Sql zu

ändern
table.Variable2 LIKE '%' || IfNull(:VarB, '%') || '%'