30 votes

Erreur Oracle "ORA-01008 : not all variables bound" avec paramètres

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

J'utilise ODT.NET d'Oracle en C# 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");

Quand je lance cette requête, le serveur renvoie :

ORA-01008: not all variables bound

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

Pourquoi la requête s'exécute-t-elle sans problème si je n'utilise que deux paramètres, mais pas trois ? L'erreur que je reçois n'a même pas de sens.

45voto

Christian13467 Points 2496

Le fournisseur ODP.Net d'Oracle utilise la liaison par position par défaut. Pour changer le comportement en liant par nom. Définissez la propriété BindByName à la vérité. Vous pouvez alors rejeter la double définition des paramètres.

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

24voto

Tony Andrews Points 67363

Cela semble stupide, mais je pense que lorsque vous utilisez deux fois la même variable bind, 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 le cas avec Native Dynamic SQL dans 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.

2voto

Hugh Jones Points 1444

Vous pouvez également envisager de supprimer la duplication des noms de paramètres 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. D'une certaine manière, je pense que c'est plus naturel.

Vous pouvez aussi changer le Sql en

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X