这是我第一次处理Oracle,而且我很难理解为什么会收到这个错误。
我在查询的where子句中使用Oracle的ODT.NET w / C#和以下代码:
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(....'行中的任何一行,则查询成功完成。
如果我只查询两个参数,而不是三个参数,为什么查询会正常运行?我收到的错误甚至没有意义
答案 0 :(得分:44)
来自oracle的ODP.Net提供程序使用bind by position作为默认值。要按名称更改要绑定的行为。将属性BindByName设置为true。你可以忽略参数的双重定义。
using(OracleCommand cmd = con.CreateCommand()) {
...
cmd.BindByName = true;
...
}
答案 1 :(得分:24)
看起来很愚蠢,但我认为当你使用相同的绑定变量两次时,你必须设置它两次:
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");
当然,PL / SQL中的Native Dynamic 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.
答案 2 :(得分:2)
您也可以考虑通过将Sql更改为
来消除Sql中重复参数名称的需要table.Variable2 LIKE '%' || :VarB || '%'
然后让客户端为任何VarB值而不是null提供'%'。在某些方面,我认为这更自然。
您也可以将Sql更改为
table.Variable2 LIKE '%' || IfNull(:VarB, '%') || '%'