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

C# ODP.NET:如何将数据从动态sql获取到数据集,c#,oracle,odp.net,timesten,C#,Oracle,Odp.net,Timesten,我的应用程序使用TimesTen DB存储数据。下面是我更新数据并返回更新行的代码 conn = new OracleConnection("My Connection"); conn.Open(); OracleTransaction tran = conn.BeginTransaction(IsolationLevel.ReadCommitted); OracleCommand command = new OracleCommand(); command = new OracleComma

我的应用程序使用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);
conn=neworacleconnection(“我的连接”);
conn.Open();
OracleTransaction tran=conn.BeginTransaction(IsolationLevel.ReadCommitted);
OracleCommand=新的OracleCommand();
command=newOracleCommand(@“声明idNo编号;
开始

从“+prefix_db+@”tbl_request_中选择id到idNo中,其中upper(status)=“PENDING”和ROWNUM匿名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;

如果无法在数据库中创建函数,请尝试替换字符串
APITT\u tbl\u请求(:prefix\u db);
函数体,但我不知道这是否有效。

同样的SQL在您使用的任何SQL工具中都有效吗?我正在使用SQL developer工具,并且我的查询运行正常。我认为参数应该具有
参数方向。输出
类型值我更改为参数方向。输出,但得到相同的错误:(问题似乎出现在您的第一次查询中,
从…
中的tbl_请求_中将id选择为idNo。请附加表
DDL
?我按您的代码运行,它显示错误{System.InvalidOperationException:由于对象的当前状态,操作无效。位于Oracle.DataAccess.Client.OracleCommand.ExecuteReaderAsyncQueue.ProcessQueue.Process()的System.Data.Common.DbDataAdapter.Fill(数据集数据集、Int32 startRecord、Int32 maxRecords、String srcTable、IDbCommand命令、CommandBehavior行为)中的(布尔重新查询、布尔填充请求、CommandBehavior行为)在ProcessQueue.cs:line 164}中,您打开了连接吗?是的,连接已打开。对不起,我缺少ExcuteOnQuery,但添加此代码时出现了不同的错误:({System.InvalidOperationException:由于对象的当前状态,操作无效。在Oracle.DataAccess.Client.OracleCommand.ExecuteOnQuery()}===================================================下面是mycode查看我的更新答案。我不知道引用光标是否可以填充
数据集
,通常
数据集
包含多个
数据表
,我假设您必须手动将它们添加到
数据集
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);