2010-08-16 92 views
2

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

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

由于服务器将在防火墙后的客户LAN上运行,并且由于涉及参数的动态特性,因此不会使用sprocs - SQL字符串内置于逻辑中。

下面是一个例子字符串:执行对目标的SQL命令时

ORA-01036: illegal variable name/number 

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

当在VS 2010中调试代码,并步入服务器代码,我们收到以下错误在oracle机器上,我们被提示输入上述语句的变量绑定 ,并且只要我们使用正确的日期格式,UPDATE语句 工作正常。

问题:

1)是有可能,甲骨文扔ORA-01036错误时,一个月的格式是错误的?

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

3)如果日期格式不是问题,恰恰是什么也ORA-1036的意思是,我如何发现 哪个变量有一个非法的名称/号码是多少?


这是取数据集(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 

这是取决于其中可能的15种类型的数据集的(WOName)从客户端程序接收一个函数,它在Oracle命令对象的ByRef并增加所需的参数到它, 的一个片段。 存在许多情况,但为了便于阅读,已将其删除。

然后将更新的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传递的参数 - 而且我知道这将会发生。所以如果这是问题,我必须解决它。有太多的可选参数和列并不总是让传入的值为这个系统打破空值。

回答

1

该错误与日期格式无关,这意味着该语句中的变量未被绑定。

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

你能用创建,绑定和执行语句的周边代码更新你的问题吗?

+0

感谢您的回答蒂洛,明天我会在工作中更新。 SF – 2010-08-16 04:52:44

-1

这是一个函数的片段,它接受数据集的类型(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 

这是取决于其中可能的15种类型的数据集的(WOName)从客户端程序接收一个函数,它在Oracle命令对象的ByRef并增加所需的参数到它, 的一个片段。 存在许多情况,但为了便于阅读,已将其删除。

然后将更新的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传递的参数 - 而且我知道这将会发生。所以如果这是问题,我必须解决它。有太多的可选参数和列并不总是让传入的值为这个系统打破空值。

+0

您应该编辑您的问题以包含此信息(我已为您完成)。答案应该是,好,*答案*。 – APC 2010-08-17 12:13:43

3

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

的解决方法是告诉甲骨文名绑定:

cmd.BindByName = true 

没有深入到你的代码的细节,这可能会或可能不会回答您的具体问题,但此设置应该是默认值,并且应该是使用参数的任何命令设置的一部分。观看这一个声明修复一些隐晦的问题真是太神奇了。

编辑:这假定您使用的是Oracle的数据访问提供程序。在.NET中,你应该使用它,而不是微软的Oracle提供商。