2011-04-18 71 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

相关问题