我想在oracle 的存储过程中直接返回结果集。如在sql server中的实现 Create Procedure sp_GetOrders
as
   Select * from Orders;
 应该怎么去实现。最好是给一个完整的存储过程的例子。
目的:是在.net中调用存储过程返回一个结果集,我们不允许在程序中嵌入sql代码
所有数据访问逻辑全部用存储过程实现。
调试成功及结贴。

解决方案 »

  1.   

    你先创建包
    CREATE OR REPLACE PACKAGE test001 IS
      TYPE datasets IS REF CURSOR;
    END test001;然后在存储过程中引用它就行了如下:
    Create Procedure sp_GetOrders

      iCursor   in out test001.datasets

    as
    tsql  varchar2(2000);
    begin
       tsql := 'Select * from Orders';
       OPEN rCursor FOR tSQL;
    end;
    这样就行了,可以得到执行tSQL后的一个结果集!
      

  2.   


     http://expert.csdn.net/Expert/topic/2058/2058571.xml?temp=.5344965
     http://expert.csdn.net/Expert/topic/1919/1919597.xml?temp=.7810785
      

  3.   

    hdkkk(diablo2) 
      老兄:
         不允许在客户端直接用sql语句
    即使select * from orders也不可以
     而要通过在存储过程中使用这样一句返回结果集
      

  4.   

    表名:test_1
    列名:num(number),name(varchar2),sex(char),major(varchar2)建立过程:
    CREATE OR REPLACE PACKAGE pkg_test
    AS
       TYPE myrctype IS REF CURSOR;
    END pkg_test;
    /CREATE PROCEDURE PRO_SLE(INPUT1 in integer,INPUT2 in VARCHAR2,p_rc out pkg_test.myrctype)
    AS
    begin
    open p_rc for 'SELECT * FROM TEST WHERE AA='||INPUT1||' AND instr(BB,'||INPUT2||')>0';
    end;
    /
    执行过程:
    declare
    v_num TEST_1.num%type;
    v_name test_1.name%type;
    v_sex test_1.sex%type;
    v_major test_1.major%type;
    v_rc pkg_test.myrctype;
    begin
    PRO_SLE(1,'1',v_rc);
    loop
    fetch v_rc into v_num,v_name,v_sex,v_major;
    exit when v_rc%notfound;
    dbms_output.put_line(v_num||v_name||v_sex||v_major);
    end loop;
    end;
      

  5.   

    定义 游标参数 如 lilac_lkd(困困)  是一种方法 
         我这里有种更好的方法 可以返回 多个数据集 
         就是利用 dbms_xmlquery.getxml 的方法 将你的select 语句以 XML 字符串的 方式返回
         定义 Clob 字段 如:
         select_str:='select * from talbename';
         clob1:=dbms_xmlquery.getxml(select_str);
         
         在前端 定义一个 TClientData  cds1;
         cds1.xmldata:=clob1; 就Ok 了@
      

  6.   

    以前,记得有很多人,说ORACLE的存储过程,不能返回一个ADO的记录集给客户端。这个说法显然是错误的。
    下面,给出个例子加以说明
    1 ORACLE端建立一个存储包
    CREATE OR REPLACE PACKAGE ado_callpkg AS
    TYPE eid IS TABLE of NUMBER(4) INDEX BY BINARY_INTEGER;
    TYPE ename IS TABLE of VARCHAR2(40) INDEX BY BINARY_INTEGER;
    PROCEDURE getEmpNames (empid OUT eid,empname OUT ename);
    end ado_callpkg;
    CREATE OR REPLACE PACKAGE BODY ado_callpkg  AS
    PROCEDURE getEmpNames (empid OUT eid,empname OUT ename) IS
    CURSOR c1 IS select employee_id,first_name||','||Middle_Initial||','||last_name as name from employee;
    cnt NUMBER DEFAULT 1;
    c c1%ROWTYPE;
    BEGIN
    open c1;
    LOOP
          FETCH c1 INTO c;
          empname(cnt):=c.name;
          empid(cnt):=c.employee_id;
          EXIT WHEN c1%NOTFOUND;  -- process the data
           cnt :=cnt+1;
      END LOOP;
    close c1;
    END;
    end ado_callpkg;2 客户端用ADO调用
        Dim cn As New ADODB.Connection
        Dim rs As New ADODB.Recordset
        Dim cmd As New ADODB.Command
        Dim str As String
        
        str = "{call ado_callpkg.getEmpNames({resultset 100,empid,empname})}"
        cn.Open "Provider=MSDAORA.1;Password=tiger;User ID=scott;Data Source=ORACLE;Persist Security Info=True"
        With cmd
            .CommandText = str
            .ActiveConnection = cn
            .CommandType = adCmdText
        End With
        
        rs.CursorLocation = adUseClient
        rs.Open cmd
        Do While Not rs.EOF
        
            Debug.Print rs.Fields(0).Value & vbTab & rs.Fields(1).Value
            rs.MoveNext
        Loop总结
    1 oracle的后台存储过程,应该通过一个类似数组并且带有数字索引的变量返回,有多少个列,就有对应多少个变量
    2 前台,调用的sql语句写法要注意,
    {call <package_name>.<prodecure name>(<input1>,<input2>,....<inputn>,{resultset <number>,<output1>,<output2>,...<outputn>})}
    注意的细节,
    (1) <number>要自己指定一个数字,表示接受的行数大小,如果太小,而实际返回的记录大于这个数字,会出错
    (2) 如果有输入参数,应该在command中创建输入参数,对应的地方用?替代,如
    {call ado_callpkg.getEmpNames(?,{resultset 100,empid,empname})}
    (3) output和你存储函数的定义一致,参数名要一样,次序也一样,否则也会出错。