Операция Oracle VB.net недопустима из-за текущего состояния объекта - PullRequest
1 голос
/ 18 апреля 2011

Хорошо, мне действительно нужно найти способ сделать это с помощью строки для закрытия вместо использования запроса на обновление, чтобы сделать все.

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()

Любая помощь была бы великолепна, если бы эта штука работала: о)

David

Ответы [ 2 ]

2 голосов
/ 19 апреля 2011

Поскольку вы не смогли найти пример создания временного указателя 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 голосов
/ 18 апреля 2011
  • Связан ли объект команды с объектом соединения?
  • Открыто ли соединение?

Как правило, у вас будет что-то вроде этого:

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, чтобы убедиться, что соединение правильно закрыто и объект (ы) правильно расположен.

...