web-dev-qa-db-fra.com

Erreur Oracle "ORA-01008: toutes les variables ne sont pas liées" avec paramètres

C'est la première fois que je traite avec Oracle, et j'ai du mal à comprendre pourquoi je reçois cette erreur.

J'utilise ODT.NET w/C # d'Oracle avec le code suivant dans la clause where d'une requête:

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

et j'ajoute les valeurs des paramètres comme ceci:

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

Lorsque j'exécute cette requête, le serveur renvoie:

ORA-01008: not all variables bound 

Si je commente l'une des lignes 'AND (....', la requête se termine avec succès.

Pourquoi la requête fonctionnerait-elle correctement si je ne fais que des requêtes avec deux paramètres, mais pas avec trois? L'erreur que je reçois n'a même pas de sens

30
John

Le fournisseur ODP.Net d'Oracle utilise par défaut la liaison par position. Pour modifier le comportement de liaison par nom. Définissez la propriété BindByName sur true. Vous pouvez ensuite ignorer la double définition des paramètres.

using(OracleCommand cmd = con.CreateCommand()) {
    ...
    cmd.BindByName = true;
    ...
}
44
Christian13467

Cela semble idiot, mais je pense que lorsque vous utilisez deux fois la même variable de liaison, vous devez la définir deux fois:

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");

C'est certainement vrai avec Native Dynamic SQL en 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.
24
Tony Andrews

Vous pouvez également envisager de supprimer la nécessité de noms de paramètres dupliqués dans votre SQL en changeant votre SQL en

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

puis demander à votre client de fournir "%" pour toute valeur de VarB au lieu de null. À certains égards, je pense que c'est plus naturel.

Vous pouvez également changer le Sql en

table.Variable2 LIKE '%' || IfNull(:VarB, '%') || '%'
2
Hugh Jones