【问题标题】:Parameterized query in Oracle troubleOracle麻烦中的参数化查询
【发布时间】:2011-08-24 05:59:04
【问题描述】:

我使用的是 Oracle.DataAccess 而不是过时的 System.Data.OracleClient,我似乎无法将多个参数传递给我的更新查询

这行得通

OracleCommand.CommandText = "UPDATE db SET column1 = :param1 WHERE column2 = 'Y'"
OracleCommand.Parameters.Add(New OracleParameter("param1", "1234"))

但我希望能够传递多个参数

这是我的完整代码

    OracleConn.Open()
    OracleCommand = OracleConn.CreateCommand()
    OracleCommand.CommandText = "UPDATE db SET column1 = :param1 WHERE column2 = :param2"
    OracleCommand.CommandType = CommandType.Text
    OracleCommand.Parameters.Add(New OracleParameter("param1", "1234"))
    OracleCommand.Parameters.Add(New OracleParameter("param2", "Y"))
    OracleCommand.ExecuteNonQuery()

我的SELECT 查询似乎在传递多个参数但不是更新参数时有效

【问题讨论】:

  • 您确实使用 OracleCommand.ExecuteNonQuery() 执行了 SQL 语句?
  • 你的 OracleCommand.CommandType 是什么
  • @Codo 我有OracleCommand.ExecuteNonQuery() 只是忘了把它放在我的例子中
  • @Cos Callis 我已经这样设置了OracleCommand.CommandType = CommandType.Text
  • ...您使用的是哪个 Oracle 客户端?

标签: asp.net oracle


【解决方案1】:

虽然我看不出您的示例有什么问题,但我想知道您是否遇到了旧的BindByName 问题。默认情况下,ODP.NET 按照将参数添加到集合中的顺序将参数绑定到查询,而不是根据您的需要基于它们的名称。尝试在您的OracleCommand 对象上将BindByName 设置为true,看看是否能解决问题。

我已经多次遇到这个问题,以至于我使用自己的工厂方法来创建自动将此属性设置为 true 的命令。

经典无用的Oracle文档here

【讨论】:

  • 打败我。当我看到 select 工作正常时,正是我的想法。
  • 天才!已经解决了 - 非常感谢,上周我一直在努力!
  • 感谢您的回答。你知道如果使用通用 ADO.NET 接口(@98​​7654328@ &c)而不是强类型接口(@98​​7654329@ &c)?是否可以在连接字符串中指定它?..
  • 我的问题已回答here
【解决方案2】:

要模拟 System.Data.OracleClient 的默认行为,您应该将 OracleCommand 设置为按名称绑定。

OracleCommand.BindByName = True

【讨论】:

    【解决方案3】:

    尝试使用指定的类型更新您的 OracleParameter。在将对象添加到参数列表之前设置对象的值。

    var param1 = new OracleParameter( "param1", OracleType.Int32 );
    param1.Value = "1234";
    
    OracleCommand.Parameters.Add( param1 );
    

    【讨论】:

    • OracleParameter 构造函数的第一个参数中不应使用冒号。应该是 OracleParameter("param1",...
    • 扎克好电话。我一定一直在查看较旧的文档。 OracleParameter 类文档download.oracle.com/docs/html/B28089_01/…
    • 如果你更新你的答案,我相信我可以删除downvote。
    【解决方案4】:

    试试这个,希望它有效。它确实编译。
    不确定您是否还必须发送提交...
    我总是通过存储过程来做这种事情,所以我在存储过程中的更新语句之后有一个提交。

    哈维·萨瑟

            OracleConnection ora_conn = new OracleConnection("connection string");
    
            OracleCommand ora_cmd = new OracleCommand("UPDATE db SET column1 = :param1 WHERE column2 = :param2", ora_conn);
            ora_cmd.CommandType = CommandType.Text;
            ora_cmd.BindByName = true;
    
            ora_cmd.Parameters.Add(":param1", OracleDbType.Varchar2, "1234", ParameterDirection.Input);
            ora_cmd.Parameters.Add(":param2", OracleDbType.Varchar2, "Y", ParameterDirection.Input);
    
            ora_cmd.ExecuteNonQuery();                
    

    【讨论】:

      【解决方案5】:

      第一个代码块是正确的:在参数名称前使用冒号,但在 OracleParameter 的第一个参数中不使用冒号。

      如果没有抛出错误,则可能是 UPDATE 运行成功,它只是不会根据 WHERE 子句及其替代参数值更新任何记录。尝试在 UPDATE 中没有 WHERE 子句的测试表上执行此操作,以确保它执行某些操作。

      【讨论】:

      • 我去掉了 WHERE 子句,但它仍然没有运行 - 如果我在没有参数的情况下更改查询,那么它工作正常
      【解决方案6】:

      这是我通常使用的结构类型(对不起,这是凭记忆):

      int rows = 0;
      using ( OracleConnection conn = new OracleConnection(connectionString) ) {
        using ( OracleCommand cmd = conn.CreateCommand() ) {
          cmd.CommandText = "UPDATE table SET column1 = ':p1 WHERE column2 = :p2";
          cmd.CommandType = CommandType.Text;
          cmd.Parameters.AddWithValue(":p1", p1Val);
          cmd.Parameters.AddWithValue(":p2", p2Val);
          rows = cmd.ExecuteNonQuery();
        }
      }
      

      关键区别在于 AddWithValue 的使用 - 我不记得我为什么最终使用它,但记得在使用其他一些方法时遇到了问题。

      【讨论】:

      • 我想我尝试过使用 AddWithValue,但它不在 Oracle.DataAccess 命名空间中 - 我认为它在 System.OracleClient 命名空间中,但那已经过时了
      • 这取决于您使用的框架版本。 Microsoft 将不再支持 System.OracleClient,但这并不意味着您必须停止使用它。
      • 我正在使用 .Net 4 框架 - 我想要一些可以更好地证明未来的东西
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-10
      • 1970-01-01
      • 2018-07-25
      相关资源
      最近更新 更多