ORA-01008: Nicht alle Variablen gebunden. Sie sind gebunden
Ich bin gekommen, über eine Oracle-problem, für das ich bislang nicht in der Lage, die Ursache zu finden.
Die folgende Abfrage funktioniert in Oracle SQL developer, aber beim laufen .NET es wirft:
ORA-01008: nicht allen Variablen gebunden
Ich versucht habe:
- Ändern der Oracle-Datentyp für lot_priority (Varchar2 oder int32).
- Ändern .NET-Datentyp für lot_priority (string oder int).
- Eine bind-variable name wird verwendet, zweimal in der Abfrage. Dies ist nicht ein problem in meinem
andere Abfragen, die den gleichen gebundene variable in mehr als einer
Lage, aber nur um sicher zu sein versuchte ich, was die zweite Instanz sein
eigene Variablen mit einer anderen : - name und Bindung getrennt. - Verschiedene Möglichkeiten, die Bindung der Variablen (siehe code auskommentiert;
auch andere). - Verschieben der bindByName () - Aufruf um.
- Ersetzen jede gebundene variable mit einer wörtlichen. Ich habe zwei separate Variablen, die das problem verursachen (:lot_pri und :lot_priprc). Es gab einige kleinere änderungen, die ich kann mich nicht erinnern, zwischen den beiden. Wechsel zu Literale aus der Abfrage arbeiten, aber Sie müssen arbeiten mit Bindung.
Abfrage und code Folgen. Variablen-Namen geändert wurden, die unschuldigen zu schützen:
SELECT rf.myrow floworder, rf.stage, rf.prss,
rf.pin instnum, rf.prid, r_history.rt, r_history.wt
FROM
(
SELECT sub2.myrow, sub2.stage, sub2.prss, sub2.pin, sub2.prid
FROM (
SELECT sub.myrow, sub.stage, sub.prss, sub.pin,
sub.prid, MAX(sub.target_rn) OVER (ORDER BY sub.myrow) target_row
,sub.hflag
FROM (
WITH floc AS
(
SELECT flow.prss, flow.seq_num
FROM rpf@mydblink flow
WHERE flow.parent_p = :lapp
AND flow.prss IN (
SELECT r_priprc.prss
FROM r_priprc@mydblink r_priprc
WHERE priprc = :lot_priprc
)
AND rownum = 1
)
SELECT row_number() OVER (ORDER BY pp.seq_num, rpf.seq_num) myrow,
rpf.stage, rpf.prss, rpf.pin,
rpf.itype, hflag,
CASE WHEN rpf.itype = 'SpecialValue'
THEN rpf.instruction
ELSE rpf.parent_p
END prid,
CASE WHEN rpf.prss = floc.prss
AND rpf.seq_num = floc.seq_num
THEN row_number() OVER (ORDER BY pp.seq_num, rpf.seq_num)
END target_rn
FROM floc, rpf@mydblink rpf
LEFT OUTER JOIN r_priprc@mydblink pp
ON (pp.prss = rpf.prss)
WHERE pp.priprc = :lot_priprc
ORDER BY pp.seq_num, rpf.seq_num
) sub
) sub2
WHERE sub2.myrow >= sub2.target_row
AND sub2.hflag = 'true'
) rf
LEFT OUTER JOIN r_history@mydblink r_history
ON (r_history.lt = :lt
AND r_history.pri = :lot_pri
AND r_history.stage = rf.stage
AND r_history.curp = rf.prid
)
ORDER BY myrow
public void runMyQuery(string lot_priprc, string lapp, string lt, int lot_pri) {
Dictionary<int, foo> bar = new Dictionary<int, foo>();
using(var con = new OracleConnection(connStr)) {
con.Open();
using(var cmd = new OracleCommand(sql.rtd_get_flow_for_lot, con)) { // Query stored in sql.resx
try {
cmd.BindByName = true;
cmd.Prepare();
cmd.Parameters.Add(new OracleParameter("lapp", OracleDbType.Varchar2)).Value = lapp;
cmd.Parameters.Add(new OracleParameter("lot_priprc", OracleDbType.Varchar2)).Value = lot_priprc;
cmd.Parameters.Add(new OracleParameter("lt", OracleDbType.Varchar2)).Value = lt;
// Also tried OracleDbType.Varchar2 below, and tried passing lot_pri as an integer
cmd.Parameters.Add(new OracleParameter("lot_pri", OracleDbType.Int32)).Value = lot_pri.ToString();
/*********** Also tried the following, more explicit code rather than the 4 lines above: **
OracleParameter param_lapp
= cmd.Parameters.Add(new OracleParameter("lapp", OracleDbType.Varchar2));
OracleParameter param_priprc
= cmd.Parameters.Add(new OracleParameter("lot_priprc", OracleDbType.Varchar2));
OracleParameter param_lt
= cmd.Parameters.Add(new OracleParameter("lt", OracleDbType.Varchar2));
OracleParameter param_lot_pri
= cmd.Parameters.Add(new OracleParameter("lot_pri", OracleDbType.Varchar2));
param_lapp.Value = lastProcedureStackProcedureId;
param_priprc.Value = lotPrimaryProcedure;
param_lt.Value = lotType;
param_lot_pri.Value = lotPriority.ToString();
//***************************************************************/
var reader = cmd.ExecuteReader();
while(reader.Read()) {
// Get values from table (Never reached)
}
}
catch(OracleException e) {
// ORA-01008: not all variables bound
}
}
}
Warum ist Oracle behauptet, dass nicht alle Variablen gebunden sind?
InformationsquelleAutor der Frage Charles Burns | 2011-09-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fand ich wie die Abfrage ausführen ohne Fehler, aber ich zögere, nennen es eine "Lösung" ohne wirklich zu verstehen, die zugrunde liegende Ursache.
Diese ähnelt eher der Beginn meiner eigentlichen Abfrage:
Den zweiten Satz der Kommentare oben, am Anfang der Unterabfrage, waren das problem. Wenn entfernt, wird die Abfrage ausgeführt. Andere Kommentare sind in Ordnung.
Dies ist nicht eine Frage von einigen Schurken oder fehlende newline verursacht die folgende Zeile kommentiert werden, da die folgende Zeile ist ein SELECT. Ein fehlender wählen Sie ergäbe einen anderen Fehler als "nicht alle Variablen gebunden."
Ich fragte herum und fand eine co-Arbeitnehmer, die in dieser -- Kommentare verursacht query-Fehler-mehrere Male.
Weiß jemand wie das kann die Ursache sein? Es ist mein Verständnis, dass die allererste Sache, die ein DBMS tun würde, mit Kommentaren ist, sehen, wenn Sie Hinweise enthalten, und wenn nicht, entfernen Sie Sie während der Analyse. Wie kann ein normaler Kommentar enthält keine Sonderzeichen (nur Buchstaben und ein Punkt) einen Fehler verursachen? Bizarr.
InformationsquelleAutor der Antwort Charles Burns
Ich weiß, das ist eine alte Frage, aber es wurde nicht richtig adressiert, so bin ich, Sie zu beantworten für andere, die vielleicht mit diesem problem.
Standardmäßig Oracle ODP.net bindet Variablen durch die position, und behandelt jede Stelle als neue variable.
Behandlung jede Kopie als eine andere variable und Einstellung es Wert ist, mehrmals wird ein Problem und ein Schmerz, als furman87 erwähnt, und könnte zu Fehlern, wenn Sie versuchen, die Abfrage so umschreiben und Dinge bewegen.
Der richtige Weg ist, um die BindByName Eigentum der OracleCommand auf true wie folgt:
Könnte man auch erstellen Sie eine neue Klasse zum Kapseln der OracleCommand Einstellung der BindByName auf true bei der Instantiierung, so dass Sie nicht haben, um den Wert jedes mal. Dies wird beschrieben in diese post
InformationsquelleAutor der Antwort Vijay Jagdale
Haben Sie zwei Verweise auf die :lot_priprc Bindung-Variablen-während es sollte verlangen, dass Sie nur setzen Sie den Wert der Variablen einmal und binden Sie es in beiden Orten, ich hatte schon Probleme wo dies nicht funktioniert hatte und zu behandeln, jede Kopie als eine andere variable. Ein Schmerz, aber es funktionierte.
InformationsquelleAutor der Antwort furman87
Auf Charles' Kommentar problem: um alles noch schlimmer machen, lassen
per Befehl Parameter, und führen Sie
wird und nach dem ändern wird die Zeichenkette von === - - -
Beide Anweisungen werden ausgeführt, Ordnung in SQL Developer. Der verkürzte code:
verwenden Oracle.ManagedDataAccess.dll Version 4.121.2.0 mit den default-Einstellungen im VS2015 .Net 4.61 Plattform.
Also irgendwo in der Aufruf-Kette, möglicherweise gibt es einen parser, der ein bisschen zu aggressiv auf der Suche nach one-line-Kommentare gestartet von -- in der commandText. Aber selbst wenn dies wäre der Fall, wird die Fehlermeldung "nicht alle Variablen gebunden" ist mindestens irreführend.
InformationsquelleAutor der Antwort Zartag
Ist es ein bug in Verwaltet ODP.net - 'Bug 21113901 : MANAGED ODP.NET ERHÖHEN ORA-1008 MIT SINGLE QUOTED CONST + BIND VAR SELECT' behoben, in patch 23530387 ersetzt durch patch 24591642
InformationsquelleAutor der Antwort durzy
Ich hatte ein ähnliches problem in einer legacy-Anwendung, aber de "--" war-string-parameter.
Ex.:
Ändern-Adresse, parameter, Wert '--' bis '' 00 ' oder andere Sache, funktioniert.
InformationsquelleAutor der Antwort Roger