2010-08-16 66 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提供商。