CREATE OR REPLACE PROCEDURE test

  v_a IN NUMBER DEFAULT NULL ,
  cv_1 OUT SYS_REFCURSOR,
  cv_2 OUT SYS_REFCURSOR

as
begin
open cv_1 for select 'aa' from dual;if(v_a is not null)then
begin
open cv_2 for select 'bb' from dual;
end;
endif;
end
----------------
如果v_a 是空的话,外面填充dateset时会报"未执行语句句柄" 错误,
但是我就是不想open cv_2 for ,只想dateset有一个table;外面对table.count 做一些业务判断。没法改
,我想实现根据业务有时返回一个table,有时返回两个table
不能让dataset固定总是两个table
但是,如果cv_2不打开的话,就报异常。
我引用的是.net 的
system.data.oracleclient.dll(oracle自己的dll没事,但是不想用那个)
用报这个异常,,报错是由于定义cv_2为输出游标,但没有打开。
引发异常: System.Data.OracleClient.OracleException: ORA-24338: 未执行语句句柄

解决方案 »

  1.   

    SQL> CREATE OR REPLACE PROCEDURE test
      2  (
      3    cv_1 OUT SYS_REFCURSOR,
      4    cv_2 OUT SYS_REFCURSOR,
      5    v_a IN NUMBER DEFAULT NULL
      6  )
      7  as
      8  begin
      9  open cv_1 for select 'aa' from dual;
     10  if v_a is not null then
     11  begin
     12  open cv_2 for select 'bb' from dual;
     13  end;
     14  end if;
     15  end;
     16  /Procedure created.SQL> exec test(:v1,:v2);PL/SQL procedure successfully completed.SQL> print :v1;'A
    --
    aaSQL>
      

  2.   

    vs2008中。OracleCommand command = new OracleCommand("test", connection);
    OracleParameter param;
                    param = new OracleParameter(
                                string.Format("v_a", 1));
                    param.Value = null;
                    command.Parameters.Add(param);
     
                    command.Connection.Open();
                    OracleDataAdapter adp = new OracleDataAdapter(command);
                    adp.Fill(ds);会报一个异常。
      

  3.   

    如果使用 microsoft 提供的 System.Data.OracleClient 确实会自动提取 cv_2 游标,即使此游标不存在。但是,可以这样变通一下,不知道是否符合 lz 的要求。create or replace procedure getjob 
    (istitle number:=1,c1 out sys_refcursor, c2 out sys_refcursor)
    is 
    begin
     open c1 for select job_id,min_salary,max_salary from jobs;
     open c2 for select job_title,min_salary,max_salary from jobs where istitle=1;
    end;
    /using System;
    using System.Data;
    using System.Data.OracleClient;namespace oraApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (OracleConnection conn =
                    new OracleConnection("Data Source=xe;User ID=hr;Password=hr;"))
                {
                    conn.Open();                OracleCommand cmd = new OracleCommand("getjob", conn);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add("istitle", OracleType.Number).Value = 0;
                    cmd.Parameters.Add("c1",OracleType.Cursor).Direction = ParameterDirection.Output;
                    cmd.Parameters.Add("c2", OracleType.Cursor).Direction = ParameterDirection.Output;                OracleDataAdapter adpt = new OracleDataAdapter(cmd);
                    DataSet ds = new DataSet();
                    adpt.Fill(ds);                foreach (DataTable dt in ds.Tables)
                    {
                        if (dt.Rows.Count > 0)
                        {
                            Console.WriteLine("Tables: ");
                            foreach (DataRow dr in dt.Rows)
                            {
                                Console.WriteLine("{0}\t{1}\t{2}", dr[0], dr[1], dr[2]);
                            }
                        }
                    }
                    Console.ReadKey();
                }
            }
        }
    }
      

  4.   

    楼主,我也碰到这问题了。ORACLE自带的DLL在哪下载,C#怎么调用啊,谢谢!