【问题标题】:Oracle "ORA-01008: not all variables bound" Error w/ ParametersOracle“ORA-01008:并非所有变量都绑定”错误带参数
【发布时间】:2010-11-28 03:59:31
【问题描述】:

这是我第一次与 Oracle 打交道,我很难理解为什么会收到此错误。

我在查询的 where 子句中使用带有 C# 的 Oracle ODT.NET 和以下代码:

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 (....' 行,则查询成功完成。

如果我只使用两个参数而不是三个参数进行查询,为什么查询会正常运行?我收到的错误甚至没有意义

【问题讨论】:

  • 能否在SQL语句执行前使用DBMS_OUTPUT打印出来?

标签: sql oracle plsql oracle10g


【解决方案1】:

oracle 的 ODP.Net 提供程序默认使用按位置绑定。将行为更改为按名称绑定。将属性 BindByName 设置为 true。比你可以忽略参数的双重定义。

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

【讨论】:

  • 这更有意义...我昨天重新安排了参数,并意识到它是通过变量的位置而不是名称绑定的(这不好);没有意识到有一个选项可以改变它
  • 这是好 Christian13467!我不知道这一点,因此我对从 8i 到 10g 的原生 .Net Oracle 数据提供程序的体验。感谢您的回答。
  • 优秀的解决方案。比复制参数要好得多。 @John - 如果可以的话,你真的应该考虑接受这个答案 - 超过 13000 人已经看过你的问题,他们应该首先看到更好的选择。 (对不起托尼)
  • 这刚刚解决了一个小时的挫败感和插入中的类型错误而头疼的问题 - 谢谢!假设我的命名参数中的名称实际上是被使用的。叹息。
  • 这是 oracle 的可怕设计。 +1
【解决方案2】:

这看起来很愚蠢,但我认为当你两次使用同一个绑定变量时,你必须设置两次:

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 中的本机动态 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.

【讨论】:

  • 成功了……不敢相信它会在那个庄园里发挥作用,但它奏效了,所以我会接受的!谢谢!
  • 不仅要多次指定,还要按照它们在查询中出现的顺序添加。
  • 我并不是要背负一个非常古老的帖子......但有谁知道这(如果多次使用必须多次添加参数)是否仍然如此?我正在处理一个奇怪的场景,其中某些东西对我来说在本地工作,但是当它由生产中的用户运行时失败了。暂时取消了更改,但对于为什么 01008 错误只显示给用户有点茫然。
【解决方案3】:

您还可以考虑通过将 Sql 更改为

来消除 Sql 中重复参数名称的需要
table.Variable2 LIKE '%' || :VarB || '%'

然后让您的客户为 VarB 的任何值而不是 null 提供“%”。在某些方面,我认为这更自然。

您也可以将 Sql 更改为

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

【讨论】:

    猜你喜欢
    • 2011-09-22
    • 2021-12-18
    • 2012-09-05
    • 2020-05-06
    • 2021-12-11
    • 1970-01-01
    • 2016-03-14
    • 2021-01-04
    • 1970-01-01
    相关资源
    最近更新 更多