2016-03-21 7 views
0

Meine Anwendung mit TimesTen DB zum Speichern von Daten. Im Folgenden finden Sie meinen Code zum Aktualisieren von Daten und zum Zurückgeben einer aktualisierten Zeile.ODP.NET: Wie kann ich Daten von dynamischen SQL zu Datensatz

conn = new OracleConnection("My Connection"); 
conn.Open(); 
OracleTransaction tran = conn.BeginTransaction(IsolationLevel.ReadCommitted); 
OracleCommand command = new OracleCommand(); 

command = new OracleCommand(@"DECLARE idNo NUMBER; 
BEGIN 
select id into idNo from " + prefix_db + @"tbl_request_in where upper(status)='PENDING' and ROWNUM <= 1 order by priority, id FOR update; 
update " + prefix_db + @"tbl_request_in set status ='Processing',begin_time= SYSDATE(),response_node='10.9.70.47' 
where upper(status) <> 'PROCESS' and upper(status) <> 'PROCESSING' and upper(status) <> 'OK' and upper(status)<>'ERROR' 
and id=idNo; 
OPEN :RETURNCURSOR for select * from APITT_tbl_request_in where id=idNo; 
END;", conn); 

command.Transaction = tran; 
command.BindByName = true; 
OracleParameter outNumPrm = command.Parameters.Add("RETURNCURSOR", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.ReturnValue); 

// create a data adapter to use with the data set 
OracleDataAdapter da = new OracleDataAdapter(command); 

// create the data set 
DataSet ds = new DataSet(); 

// fill the data set 
da.Fill(ds); 

Und ich gebe Fehler

{Oracle.DataAccess.Client.OracleException ORA-01722: ungültige Nummer
bei Oracle.DataAccess.Client.OracleException.HandleErrorHelper (Int32 errCode OracleConnection conn , IntPtr opsErrCtx, OpoSqlValCtx * pOpoSqlValCtx, Objekt src, String Prozedur, Boolean bÜberprüfen) bei Oracle.DataAccess.Client.OracleException.HandleError (Int32 errCode OracleConnection anschl, IntPtr opsErrCtx, Objekt src, Boolean bÜberprüfen) bei Oracle.DataAccess.Client.OracleDataReader.Read() bei System.Data.Common.DataAdapter.FillLoadDataRow (SchemaMapping mapping) bei System.Data.Common.DataAdapter.FillFromReader (Datensatz Datensatz Datentabelle Datentabelle, String srcTable, DataReaderContainer Datareader Int32 startrecord, Int32 maxRecords, Datacolumn parentChapterColumn, Object parentChapterValue) bei System.Data.Common.DataAdapter.Fill (DataSet dataSet, String srcTable, IDataReader Datareader Int32 startrecord, Int32 maxRecords) bei Oracle.DataAccess.Client .OracleDataAdapter.Fill (DataSet dataSet, Zeichenfolge srcTable, IDataReader dataReader, Int32 startRecord, Int32 maxRecords) bei Oracle.DataAccess.Client.OracleDataAdapter.Fill (DataSet-Daten Set, Int32 startrecord, Int32 maxRecords, String srcTable, IDbCommand Befehl, CommandBehavior Verhalten) bei System.Data.Common.DbDataAdapter.Fill (DataSet dataSet)

Wie kann ich es beheben?

+0

Funktioniert die gleiche SQL in den SQL-Tools, die Sie verwenden? –

+0

Ich benutze SQL Developer Tool, und meine Abfrage läuft ok –

+0

Ich denke, der Parameter sollte 'ParameterDirection.Output' Typ Wert haben –

Antwort

0

Ein anonymer PL/SQL-Block kann keinen Wert zurückgeben. Schreiben Sie eine Funktion wie folgt aus:

CREATE OR REPLACE FUNCTION APITT_tbl_request(prefix_db IN VARCHAR2) RETURN SYS_REFCURSOR AS 
    idNo NUMBER; 
    res SYS_REFCURSOR; 
BEGIN 
    EXECUTE IMMEDIATE 'SELECT ID ' 
     ||'FROM '|| prefix_db || 'tbl_request_in ' 
     ||'WHERE UPPER(status)=''PENDING'' AND ROWNUM <= 1 ORDER BY priority, ID FOR UPDATE' 
    INTO idNo; 

    EXECUTE IMMEDIATE 'UPDATE '|| prefix_db || 'tbl_request_in SET status =''Processing'', begin_time= :bt, response_node=''10.9.70.47'' ' 
     ||'WHERE UPPER(status) <> ''PROCESS'' AND UPPER(status) <> ''PROCESSING'' AND UPPER(status) <> ''OK'' AND UPPER(status)<>''ERROR'' AND ID= :id' 
    USING SYSDATE, idNo 

    OPEN res FOR SELECT * FROM APITT_tbl_request_in WHERE ID=idNo; 
    RETURN res; 
END; 

und rufen Sie diese Funktion wie

DataTable dt = new DataTable(); 
OracleCommand command = new OracleCommand(@"BEGIN :RETURNCURSOR := APITT_tbl_request(:prefix_db); END;"); 
command.CommandType = CommandType.Text; 
command.Parameters.Add("RETURNCURSOR", OracleDbType.RefCursor, ParameterDirection.ReturnValue); 
command.Parameters.Add("prefix_db", OracleDbType.Varchar2, ParameterDirection.Input).Value = prefix_db; 
OracleDataAdapter da = new OracleDataAdapter(command); 
da.Fill(dt); 

Wenn Sie die Funktion in der Datenbank erstellen können, versuchen Zeichenfolge APITT_tbl_request(:prefix_db); mit der Funktion Körper zu ersetzen, aber ich weiß nicht, wenn das geht.

+0

Ich renne von Ihrem Code, es zeigt Fehler {System.InvalidOperationException: Operation ist nicht gültig aufgrund des aktuellen Status des Objekts. bei Oracle.DataAccess.Client.OracleCommand.ExecuteReader (Boolean Requery, Boolean fillRequest , CommandBehavior-Verhalten) bei Oracle.DataAccess.Client.OracleDataAdapter.Fill (DataSet dataSet, Int32 startrecord, Int32 maxRecords, String srcTable, IDbCommand Befehl, CommandBehavior Verhalten) bei System.Data.Common.DbDataAdapter.Fill (DataSet dataSet) bei AsyncQueue.ProcessQueue .Process() in ProcessQueue.cs: Zeile 164} –

+0

Haben Sie die Verbindung geöffnet? –

+0

Ja, die Verbindung wurde geöffnet –

Verwandte Themen