高手请进 存储过程返回结果集问题

ljg2003 2003-08-26 11:52:34
我想在oracle 的存储过程中直接返回结果集。如在sql server中的实现

Create Procedure sp_GetOrders
as
Select * from Orders;


应该怎么去实现。最好是给一个完整的存储过程的例子。
目的:是在.net中调用存储过程返回一个结果集,我们不允许在程序中嵌入sql代码
所有数据访问逻辑全部用存储过程实现。
调试成功及结贴。
...全文
14 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
enhydraboy 2003-08-27
  • 打赏
  • 举报
回复
以前,记得有很多人,说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和你存储函数的定义一致,参数名要一样,次序也一样,否则也会出错。
Blackride 2003-08-27
  • 打赏
  • 举报
回复
定义 游标参数 如 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 了@
LGQDUCKY 2003-08-26
  • 打赏
  • 举报
回复

http://expert.csdn.net/Expert/topic/2058/2058571.xml?temp=.5344965
http://expert.csdn.net/Expert/topic/1919/1919597.xml?temp=.7810785
lilac_lkd 2003-08-26
  • 打赏
  • 举报
回复
你先创建包
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后的一个结果集!
zjhclf 2003-08-26
  • 打赏
  • 举报
回复
为什么不变通一下,存储过程中把结果集插入一张表中,程序前台对表进行操作好了!
lynx1111 2003-08-26
  • 打赏
  • 举报
回复
表名: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;
xys2003 2003-08-26
  • 打赏
  • 举报
回复
hdkkk(diablo2)
老兄:
不允许在客户端直接用sql语句
即使select * from orders也不可以
而要通过在存储过程中使用这样一句返回结果集
LGQDUCKY 2003-08-26
  • 打赏
  • 举报
回复
只要能实现目的,而且简单的方法,都是好方法
hdkkk 2003-08-26
  • 打赏
  • 举报
回复
也有道理啊
=-----------
为什么不变通一下,存储过程中把结果集插入一张表中,程序前台对表进行操作好了!

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧