Oracle & # 8220; ORA-01008: non tutte le variabili associate & # 8221; Errore con / Parametri
Domanda
Questa è la prima volta che ho avuto a che fare con Oracle e non riesco a capire perché ricevo questo errore.
Sto usando ODT.NET di Oracle con C # con il seguente codice nella clausola where di una query:
WHERE table.Variable1 = :VarA
AND (:VarB IS NULL OR table.Variable2 LIKE '%' || :VarB || '%')
AND (:VarC IS NULL OR table.Variable3 LIKE :VarC || '%')
e sto aggiungendo i valori dei parametri in questo modo:
cmd.Parameters.Add("VarA", "24");
cmd.Parameters.Add("VarB", "test");
cmd.Parameters.Add("VarC", "1234");
Quando eseguo questa query, il server restituisce:
ORA-01008: not all variables bound
Se commento una delle righe "AND (....", la query si completa correttamente.
Perché la query dovrebbe andare bene se sto interrogando solo con due parametri, ma non con tre? L'errore che sto ricevendo non ha nemmeno senso
Soluzione
Il provider ODP.Net di Oracle utilizza come impostazione predefinita il bind per posizione. Per modificare il comportamento da associare per nome. Impostare la proprietà BindByName su true. Quindi puoi ignorare la doppia definizione di parametri.
using(OracleCommand cmd = con.CreateCommand()) {
...
cmd.BindByName = true;
...
}
Altri suggerimenti
Sembra sciocco, ma penso che quando usi la stessa variabile bind due volte devi impostarla due volte:
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");
Certamente questo è vero con SQL dinamico nativo 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.
Potresti anche considerare di rimuovere la necessità di nomi di parametri duplicati nel tuo Sql modificando il tuo Sql in
table.Variable2 LIKE '%' || :VarB || '%'
e quindi indurre il client a fornire '%' per qualsiasi valore di VarB anziché null. In un certo senso penso che sia più naturale.
Puoi anche cambiare l'Sql in
table.Variable2 LIKE '%' || IfNull(:VarB, '%') || '%'