【问题标题】:UPDATE statement in OracleOracle 中的 UPDATE 语句
【发布时间】:2010-08-16 02:06:24
【问题描述】:

我们正在构建一个客户端程序,其中用于存储在具有 Oracle 后端的 Web 服务器中的参数在 .Net 客户端程序中设置,并通过 Web 服务作为数据集上传。

在网络服务代码中,从数据集中读取数据并添加到网络服务器(Oracle 后端)上的 UPDATE 语句中。

因为服务器将在防火墙后面的客户 LAN 上运行,并且由于所涉及参数的动态特性,所以没有使用存储过程 - SQL 字符串内置在逻辑中。

这是一个示例字符串:

UPDATE WorkOrders 
   SET TravelTimeHours = :TravelTimeHours, 
       TravelTimeMinutes = :TravelTimeMinutes,  
       WorkTimeHours = :WorkTimeHours, 
       WorkTimeMinutes = :WorkTimeMinutes, 
       CompletedPersonID = :CompletedPersonID, 
       CompletedPersonName = :CompletedPersonName, 
       CompleteDate = :CompleteDate 
 WHERE WorkOrderNumber = :WorkOrderNumber

在 VS 2010 中调试代码并单步执行服务器代码时,我们收到以下错误:

ORA-01036: illegal variable name/number

在目标oracle机器上执行SQL命令时,提示输入绑定 上面语句的变量,只要我们使用正确的日期格式,UPDATE语句 工作正常。

问题:

1) 月份格式错误时oracle会抛出ORA-01036错误吗?

2) 为什么我们不必从运行在 Oracle 机器上的 ASP.net 网站转换日期格式? Oracle 是否有排除绑定变量输入屏幕的默认转换例程?

3) 如果日期格式不是问题,ORA-1036 究竟是什么意思,我如何发现 哪个变量的名称/编号非法?


这是一个函数的 sn-p,它采用数据集的类型 (WOName) 并返回适当的 SQL 字符串。 许多案例存在,但为了便于阅读已被删除。

Private Function GetMainSQLString(ByVal WOName As String) As String
    Dim Result As String = ""
    Select Case WOName
        Case "Monthly Site Inspection"              
            Dim sb As New StringBuilder
            sb.Append("UPDATE WorkOrders SET ")
            sb.Append("CompletedPersonID = :CompletedPersonID, CompletedPersonName = :CompletedPersonName, CompleteDate = :CompleteDate, ")
            sb.Append("SupervisorID = :SupervisorID, SupervisorName = :SupervisorName ")
            sb.Append("WHERE WorkOrderNumber = :WorkOrderNumber")
            Result = sb.ToString
    End Select
    Return Result
End Function

这是一个函数的 sn-p,它接受 Oracle 命令对象 byRef 并向其添加所需的参数, 取决于从客户端程序接收到的可能的 15 种数据集(WOName)中的哪一种。 许多案例存在,但为了便于阅读已被删除。

然后将更新后的 Cmd 对象返回到主程序逻辑,其中调用 ExecuteNonQuery()。

下面params的测试值如下:

dr.Item("CompletedPersonID")    21
dr.Item("CompletedPersonName")  Pers Name
dr.Item("CompleteDate")     #8/16/2010#
dr.Item("SupervisorID")     24
dr.Item("SupervisorName")   Sup Name
dr.Item("WorkOrderNumber")  100816101830


Private Function addMainCmdParams(ByVal WOName As String, ByRef cmd As OracleCommand, ByVal dr As DataRow) As OracleCommand
    Select Case WOName
        Case "Monthly Site Inspection"              
            cmd.Parameters.Add(":CompletedPersonID", Oracle.DataAccess.Client.OracleDbType.Int32).Value = dr.Item("CompletedPersonID")
            cmd.Parameters.Add(":CompletedPersonName", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("CompletedPersonName")
            cmd.Parameters.Add(":CompleteDate", Oracle.DataAccess.Client.OracleDbType.Date).Value = dr.Item("CompleteDate")
            cmd.Parameters.Add(":SupervisorID", Oracle.DataAccess.Client.OracleDbType.Int32).Value = dr.Item("SupervisorID")
            cmd.Parameters.Add(":SupervisorName", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("SupervisorName")
            cmd.Parameters.Add(":WorkOrderNumber", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("WorkOrderNumber")
    End Select
    Return cmd
End Function

今天运行时,这个精确的代码是成功的;但另一个类似的情况不是。我仍然不相信 Oracle 执行的任何隐式类型转换(如果有的话)——我特别怀疑 Oracle 如何处理通过 dbNull.value 传递的任何这些参数——我知道它会发生。所以如果这是问题,我将不得不解决它。有太多的可选参数和列并不总能获得传入的值,以使该系统无法在空值上中断。

【问题讨论】:

    标签: sql oracle ora-01036


    【解决方案1】:

    一个可能导致此错误的 Oracle “陷阱”是这样一个事实,即默认情况下,Oracle 按顺序而不是按名称将参数映射到查询中的参数符号。如果参数的数量/类型不匹配,则会出现类似这样的错误。

    解决方法是告诉Oracle按名称绑定:

    cmd.BindByName = true
    

    如果不深入了解您的代码细节,这可能是也可能不是您特定问题的答案,但此设置应该是默认设置,并且应该是任何使用参数的命令设置的一部分。看到这句话解决了一些晦涩难懂的问题,真是太神奇了。

    编辑:假设您使用的是 Oracle 的数据访问提供程序。在 .NET 中,您应该使用它,而不是 Microsoft 的 Oracle 提供程序。

    【讨论】:

      【解决方案2】:

      该错误与日期格式无关,表示语句中的变量未绑定。

      可能就像拼写错误一样简单(如果 Oracle 在错误消息中包含变量名会很好)。

      您能否用创建、绑定和执行语句的周围代码更新您的问题?

      【讨论】:

      • 谢谢你的回答Thilo,我明天上班更新。顺丰
      【解决方案3】:

      这是一个函数的 sn-p,它采用数据集的类型 (WOName) 并返回适当的 SQL 字符串。 许多案例存在,但为了便于阅读已被删除。

      Private Function GetMainSQLString(ByVal WOName As String) As String
          Dim Result As String = ""
          Select Case WOName
              Case "Monthly Site Inspection"              
                  Dim sb As New StringBuilder
                  sb.Append("UPDATE WorkOrders SET ")
                  sb.Append("CompletedPersonID = :CompletedPersonID, CompletedPersonName = :CompletedPersonName, CompleteDate = :CompleteDate, ")
                  sb.Append("SupervisorID = :SupervisorID, SupervisorName = :SupervisorName ")
                  sb.Append("WHERE WorkOrderNumber = :WorkOrderNumber")
                  Result = sb.ToString
          End Select
          Return Result
      End Function
      

      这是一个函数的 sn-p,它接受 Oracle 命令对象 byRef 并向其添加所需的参数, 取决于从客户端程序接收到的可能的 15 种数据集(WOName)中的哪一种。 许多案例存在,但为了便于阅读已被删除。

      然后将更新后的 Cmd 对象返回到主程序逻辑,其中调用 ExecuteNonQuery()。

      下面params的测试值如下:

      dr.Item("CompletedPersonID")    21
      dr.Item("CompletedPersonName")  Pers Name
      dr.Item("CompleteDate")     #8/16/2010#
      dr.Item("SupervisorID")     24
      dr.Item("SupervisorName")   Sup Name
      dr.Item("WorkOrderNumber")  100816101830
      
      
      Private Function addMainCmdParams(ByVal WOName As String, ByRef cmd As OracleCommand, ByVal dr As DataRow) As OracleCommand
          Select Case WOName
              Case "Monthly Site Inspection"              
                  cmd.Parameters.Add(":CompletedPersonID", Oracle.DataAccess.Client.OracleDbType.Int32).Value = dr.Item("CompletedPersonID")
                  cmd.Parameters.Add(":CompletedPersonName", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("CompletedPersonName")
                  cmd.Parameters.Add(":CompleteDate", Oracle.DataAccess.Client.OracleDbType.Date).Value = dr.Item("CompleteDate")
                  cmd.Parameters.Add(":SupervisorID", Oracle.DataAccess.Client.OracleDbType.Int32).Value = dr.Item("SupervisorID")
                  cmd.Parameters.Add(":SupervisorName", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("SupervisorName")
                  cmd.Parameters.Add(":WorkOrderNumber", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("WorkOrderNumber")
          End Select
          Return cmd
      End Function
      

      今天运行时,这个精确的代码是成功的;但另一个类似的情况不是。我仍然不相信 Oracle 执行的任何隐式类型转换(如果有的话)——我特别怀疑 Oracle 如何处理通过 dbNull.value 传递的任何这些参数——我知道它会发生。所以如果这是问题,我将不得不解决它。有太多的可选参数和列并不总能获得传入的值,以使该系统无法在空值上中断。

      【讨论】:

      • 您应该编辑您的问题以包含此信息(我已为您完成)。答案应该是,嗯,answers
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 2015-11-19
      相关资源
      最近更新 更多