这是第一次我已经经历了甲骨文,和我有一个很难理解为什么我收到此错误。
我使用的是Oracle的ODT.NET W / C#与下面的代码查询的WHERE子句中:
WHERE table.Variable1 = :VarA
AND (:VarB IS NULL OR table.Variable2 LIKE '%' || :VarB || '%')
AND (:VarC IS NULL OR table.Variable3 LIKE :VarC || '%')
和我添加像这样的参数值:
cmd.Parameters.Add("VarA", "24");
cmd.Parameters.Add("VarB", "test");
cmd.Parameters.Add("VarC", "1234");
当我运行此查询,服务器返回:
ORA-01008: not all variables bound
如果我注释掉无论是“AND(....”行,查询成功完成。
为什么会通过正常的运行查询,如果我只用两个参数查询,但不是三个? 我收到甚至没有意义的错误
Oracle的ODP.Net提供商通过为默认位置使用绑定。 要更改名称绑定的行为。 设置性能BindByName为true。 比你可以辞退参数的双重定义。
using(OracleCommand cmd = con.CreateCommand()) {
...
cmd.BindByName = true;
...
}
这似乎愚蠢,但我认为,当你使用相同的绑定变量两次,你必须设置两次:
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");
当然,这是真的与本地动态SQL在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.
您还可以考虑通过改变您的SQL来消除对您的SQL复制的参数名称需要
table.Variable2 LIKE '%' || :VarB || '%'
然后让你的客户对VarB,而不是空的任意值提供“%”。 在某些方面,我认为这是更自然。
你也可以更改SQL来
table.Variable2 LIKE '%' || IfNull(:VarB, '%') || '%'