首页 文章

ODP.NET:如何从动态sql获取数据到数据集

提问于
浏览
0

我的应用程序使用TimesTen DB来存储数据 . 下面是我更新数据并返回更新行的代码 .

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

我给出了错误

{Oracle.DataAccess.Client.OracleException ORA-01722:Oracle上的Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode,OracleConnection conn,IntPtr opsErrCtx,OpoSqlValCtx * pOpoSqlValCtx,Object src,String procedure,Boolean bCheck)中的无效数字System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping mapping)中的Oracle.DataAccess.Client.OracleDataReader.Read().DataAccess.Client.OracleException.HandleError(Int32 errCode,OracleConnection conn,IntPtr opsErrCtx,Object src,Boolean bCheck) System.Data.Com上的System.Data.Common.DataAdapter.FillFromReader(DataSet数据集,DataTable datatable,String srcTable,DataReaderContainer dataReader,Int32 startRecord,Int32 maxRecords,DataColumn parentChapterColumn,Object parentChapterValue),System.Data.Common.DataAdapter.Fill(DataSet dataSet,String Oracle.DataAccess.Client.OracleDataAdapter.Fill中的srcTable,IDataReader dataReader,Int32 startRecord,Int32 maxRecords)(DataSet dataSet,String srcTable,IDataReader dataReade)在System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)的Oracle.DataAccess.Client.OracleDataAdapter.Fill(DataSet dataSet,Int32 startRecord,Int32 maxRecords,String srcTable,IDbCommand command,CommandBehavior behavior)中的r,Int32 startRecord,Int32 maxRecords) )

我该如何解决?

1 回答

  • 0

    匿名PL / SQL块不能返回任何值 . 写一个这样的函数:

    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;
    

    并调用此函数

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

    如果您无法在数据库中创建函数,请尝试将字符串 APITT_tbl_request(:prefix_db); 替换为函数体,但我不知道这是否有效 .

相关问题