2011-04-18 93 views
1

好吧,我真的需要找到一種方法來通過字符串來做到這一點,而不是使用更新查詢來做到這一點。VB.net由於對象的當前狀態,Oracle操作無效

Dim theXMLCode As OracleClob 
Dim OracleConnection2 As New OracleConnection() 
Dim dr2 As OracleDataReader 
Dim holdXML As String = "" 

Public Function connectToOracleDB2() As Boolean 
    OracleConnection2.ConnectionString = "User Id=" & dbUserId & ";Password=" & dbPassword & ";Data Source=(DESCRIPTION=(ADDRESS_LIST=" & _ 
             "(ADDRESS=(PROTOCOL=TCP)(HOST=" & dbHost & ")(PORT=" & dbPort & ")))" & _ 
            "(CONNECT_DATA=(SERVICE_NAME=" & dbServiceName & ")))" 

    Try 
     OracleConnection2.Open() 
     Return True 
    Catch ee As Exception 
     OracleConnection2.Close() 
     Return False 
    End Try 
End Function 

    Dim strSQL = "UPDATE CSR.TARGET ces " & _ 
       "SET  (STATUS_CODE, COMPLETE_DATE, DATA) = " & _ 
        "(SELECT 'ERROR', '', (:XML_DATA) " & _ 
        "FROM  CSR.SOURCE C " & _ 
        "WHERE  (c.EID = ces.EID) " & _ 
        "AND  c.STATUS_CODE = 'ERROR') " & _ 
       "WHERE EXISTS (SELECT 1 " & _ 
       "FROM  CSR.SOURCE C " & _ 
       "WHERE (c.EID = ces.EID) " & _ 
       "AND  c.STATUS_CODE = 'ERROR')" 

     Try 
      Dim parmData As New OracleParameter 

      With parmData 
       .Direction = ParameterDirection.Input 
       .OracleDbType = OracleDbType.Clob 
       .ParameterName = "XML_DATA" 
       .Value = holdXML 
      End With 

      OracleCommand2.Parameters.Add(parmData) 
      OracleCommand2.CommandText = strSQL 
      OracleCommand2.ExecuteNonQuery() 

,但我得到的錯誤:

錯誤:操作無效由於對象的當前狀態。

就行了:

OracleCommand2.ExecuteNonQuery() 

任何幫助將是巨大的,讓這件事的工作:O)

大衛

+0

是holdXML是臨時LOB嗎?請參閱http://msdn.microsoft.com/en-us/library/cydxhzhz(v=vs.80).aspx在.NET中使用Oracle BLOBs – tawman 2011-04-18 16:42:25

+0

holdXML是一個從CLOB填充的字符串(blah.value )。我需要找到一種方法將其轉換回CLOB並再次將其插入到數據庫中。你發佈的鏈接似乎沒有使用CLOB? – StealthRT 2011-04-18 17:44:36

+0

MSDN鏈接中有一個CLOB示例。 Oracle BLOB/CLOB是指針,你不能直接從.NET更新它們。 Google /搜索dbms_lob.createtemporary PL/SQL幫助程序。 – tawman 2011-04-18 18:36:20

回答

2

由於您找不到創建臨時高亮指針的示例,因此以下是C#中使用以前項目中的Microsoft Enterprise Library的示例。此示例與存儲過程接口,但在使用SQL更新和BLOB/CLOB時採用相同的方法:

internal static void Save(Attachments attachment) 
    { 
     try 
     { 
      // Microsoft Enterprise Library does not provide support for Oracle BLOB objects 
      // The Microsoft Data Provider for Oracle needs to allocate a BLOB pointer in memory first 
      // while running in the context of a database transaction. Once the placeholder is allocated, 
      // the byte stream is written to the handler and then passed to Oracle to update the database 
      // 
      OracleConnection connection = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connstring_devl"].ConnectionString); 
      connection.Open(); 
      OracleTransaction transaction = connection.BeginTransaction(); 
      OracleCommand command = connection.CreateCommand(); 
      command.Transaction = transaction; 
      command.CommandText = "declare xx blob; begin dbms_lob.createtemporary(xx, false, 0); :tempblob := xx; end;"; 
      command.Parameters.Add(new OracleParameter("tempblob", OracleType.Blob)).Direction = ParameterDirection.Output; 
      command.ExecuteNonQuery(); 

      OracleLob tempLob = (OracleLob)command.Parameters[0].Value; 
      tempLob.BeginBatch(OracleLobOpenMode.ReadWrite); 
      if (attachment.FileContent != null) 
       tempLob.Write(attachment.FileContent, 0, attachment.FileContent.Length); 
      tempLob.EndBatch(); 

      command.Parameters.Clear(); 
      command.CommandText = MC_SAVE_ATTACHMENT; 
      command.CommandType = CommandType.StoredProcedure; 

      command.Parameters.Add(new OracleParameter("IN_USER_ID", OracleType.VarChar)).Value = attachment.UserID; 
      command.Parameters.Add(new OracleParameter("IN_FILE_CONTENT", OracleType.Blob)).Value = tempLob; 
      command.Parameters.Add(new OracleParameter("ERROR_DESC", OracleType.VarChar, 4000)).Direction = ParameterDirection.Output; 

      command.ExecuteNonQuery(); 
      transaction.Commit(); 

      //Check errors and handle it (log, throw exception etc) 
      errors = command.Parameters["error_desc"].Value.ToString(); 
      HandleExceptions.CheckError(errors); 
     } 
     catch (Exception e) 
     { 
      string errMsg = e.Message; 
      throw; 
     } 
    } 
2
  • 是與連接對象關聯的命令對象?
  • 連接是否打開?

一般情況下,你有這樣的事情:

Dim conn as new OracleConnection() 'This may have parameters, such as the connection string 
OracleCommand2.Connection = conn 
conn.Open() 
' execute the command 
conn.Close() 

重要:此代碼是凌亂徒手代碼。我不再那麼熟悉VB語法,但在C#中,您將在using聲明的聲明中實例化OracleConnection對象。如果VB中沒有這樣的東西(儘管我懷疑它存在),那麼你最好將它包裝在try/catch /中,以確保連接正確關閉並且對象正確放置。

+0

用這些對象更新了OP。我有他們,但忘了包括他們。雖然我不明白你的例子是如何解決我得到的錯誤的? – StealthRT 2011-04-18 17:42:40

+1

在VB.NET中,其['Using'](http://msdn.microsoft.com/en-us/library/htd05whh.aspx) – 2011-04-18 17:45:39

+0

@StealthRT:即使使用更新後的代碼,連接是否在任何地方打開?自從我使用ADO.NET對象以來已經有一段時間了,但我似乎回想起在運行命令(以及後來的'.Close()')之前,需要在連接對象上調用'.Open()') 。 – David 2011-04-18 17:46:19

相關問題