如何在参数中调用sys_refcursor函数?

时间:2013-12-08 08:49:50

标签: c# oracle11g

有一个函数有sys_refcursor作为IN参数。我使用此函数在表中插入多个记录。 我有两张桌子Err,Err2:

CREATE TABLE "Err" ("code" NUMBER(20) NOT NULL ,"msg" VARCHAR2(200 BYTE) NULL 

CREATE TABLE "Err2" ("code" NUMBER(20) NOT NULL ,"msg" VARCHAR2(200 BYTE) NULL 

我使用以下代码将记录从Err复制到Err2

        OracleCommand cmd = con.CreateCommand();
        cmd.CommandText = "begin open :1 for  select * from \"Err\" ; end;";
        OracleParameter outcur = cmd.Parameters.Add("outcur", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);
        cmd.ExecuteNonQuery();

        cmd.Parameters.Clear();
        cmd.CommandText ="RegisterErrCollection";

        cmd.BindByName = true;
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add("p_ErrCollection", OracleDbType.RefCursor, outcur.Value, ParameterDirection.Input);
        cmd.Parameters.Add("return_value", OracleDbType.Int32, DBNull.Value, ParameterDirection.ReturnValue);
        cmd.ExecuteNonQuery();

它返回一个refcursor作为输出,并作为IN参数传递给该函数:

FUNCTION RegisterErrCollection(P_ERRCOLLECTION IN SYS_REFCURSOR)  RETURN NUMBER AS
Contrac_rc "Err"%rowtype;
BEGIN
  Loop
 Fetch P_ERRCOLLECTION Into Contrac_rc;
  EXIT WHEN P_ERRCOLLECTION%NOTFOUND;
   Insert into "Err2"("code","msg")
   Values(Contrac_rc."code",Contrac_rc."msg");
 End Loop;
  RETURN 1;
END;

是的,效果很好! 但我想用新数据而不是Err记录来调用该函数。我想我必须将我的数据(它放在DataTableList<ErrObject>中)转换为OracleRefCursor。 现在,如何使用我自己的数据实例化OracleRefCursor?(类似于DataTable

1 个答案:

答案 0 :(得分:0)

您可以使用一个相对简单的技巧来完成此任务:而不是从表Err中选择,您可以从dual中选择并动态构建您的select语句。

第一个命令是这样的:

cmd.CommandText =
    "begin" +
    "    open :1 for" +
    "        select 1 code, 'Message1' msg from dual" +
    "        union" +
    "        select 2, 'Message2' from dual" +
    "        union" +
    "        select 3, 'Message3' from dual"
    "end;";

这为您提供了一个光标,其中包含您指定的数据,然后您可以将其用作RegisterErrCollection函数中的参数。使用您自己的数据替换123Message1Message2Message3或者指定较少或更多消息。

据我所知,没有办法直接使用DataTable或数据列表作为sys_refcursor输入参数。