我们正在构建一个客户端程序,其中存储在具有 Oracle 后端的 Web 服务器中的参数在 .Net 客户端程序中设置,并通过 Web 服务作为数据集上传。
在 Web 服务代码中,从数据集中读取数据并添加到 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 究竟是什么意思,我如何发现 WHICH 变量的名称/编号是非法的?
这是一个函数片段,它采用数据集的类型 (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
这是一个函数片段,它接受 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 传递的任何这些参数——我知道它会发生。所以如果这是问题,我将不得不解决它。有太多的可选参数和列并不总是让这个系统传入的值在空值上中断。