2011-04-18 6 views
1

Хорошо, мне действительно нужно найти способ сделать это с помощью строки в clob вместо использования запроса на обновление, чтобы сделать все.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() 

Любая помощь будет здорово, чтобы получить эту вещь работу: о)

Дэвид

+0

Is holdXML a temp LOB? См. Http://msdn.microsoft.com/en-us/library/cydxhzhz(v=vs.80).aspx для работы с Oracle BLOB в .NET. – tawman

+0

holdXML - это строка, заполненная из CLOB (blah.value). Мне нужно найти способ конвертировать его обратно в CLOB и снова вставить в базу данных. Ссылка, которую вы разместили, похоже, не использует CLOB? – StealthRT

+0

В ссылке MSDN есть пример CLOB. Oracle BLOB/CLOB являются указателями, и вы не можете обновлять их непосредственно из .NET. Google/Поиск помощника dbms_lob.createtemporary PL/SQL. – tawman

ответ

2

Поскольку вы не смогли найти пример создания временного указателя lob, вот пример в 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# вы должны создать экземпляр объекта OracleConnection внутри объявления инструкции using. Если в VB нет такой вещи (хотя я подозреваю, что есть), вы можете ее обернуть в try/catch/finally, чтобы убедиться, что соединение правильно закрыто и объекты правильно установлены.

+0

Обновлен OP с этими объектами. У меня были они, но я забыл их включить. Я не вижу, как ваш пример исправил ошибку, которую я получаю, хотя? – StealthRT

+1

В VB.NET его ['Использовать'] (http://msdn.microsoft.com/en-us/library/htd05whh.aspx) –

+0

@StealthRT: Даже с обновленным кодом подключается ли соединение где угодно? Прошло некоторое время с тех пор, как я использовал объекты ADO.NET, но, похоже, мне кажется, что нужно вызвать '.Open()' в объекте соединения перед запуском команды (и, впоследствии, '.Close()' afterward) , – David

Смежные вопросы