我正在尝试编写一个带有数字n的存储过程,并返回给定查询的前n个结果,专门锁定这n行。我对SQL有点新,我在正确匹配数据类型时遇到了一些困难。
我的包规格如下:
PACKAGE package IS
Type out_result_type is REF CURSOR;
PROCEDURE stored_proc
(in_n IN NUMBER DEFAULT 10,
out_list IN OUT out_result_type);
然后我在过程体中定义光标,如下所示:
CURSOR OUT_RESULT_TYPE IS
SELECT a.id
FROM schema.table a
WHERE (some conditions) AND rownum <= in_n;
稍后我会尝试将光标的结果提取到输出变量中:
OPEN OUT_RESULT_TYPE;
FETCH OUT_RESULT_TYPE INTO out_list; -- error on this line
CLOSE OUT_RESULT_TYPE;
但是这个代码没有编译; oracle抱怨out_list已经被定义为具有冲突的数据类型。知道如何解决这个问题吗?这让我发疯了!
提前致谢。
答案 0 :(得分:1)
CREATE OR REPLACE PACKAGE pkg_test
AS
TYPE tt_cur IS REF CURSOR;
PROCEDURE prc_cur (retval OUT tt_cur);
END;
CREATE OR REPLACE PACKAGE BODY pkg_test
AS
PROCEDURE prc_cur (retval OUT tt_cur)
AS
BEGIN
OPEN retval
FOR
SELECT *
FROM dual;
END;
END;
如果您想锁定,请使用:
CREATE OR REPLACE PACKAGE BODY pkg_test
AS
PROCEDURE prc_cur (retval OUT tt_cur)
AS
BEGIN
OPEN retval
FOR
SELECT a.id
FROM schema.table a
WHERE (some conditions)
AND rownum <= in_n
ORDER BY
column
-- Never forget ORDER BY!
FOR UPDATE;
END;
END;
答案 1 :(得分:0)
您的out_list
类型必须错误。考虑(脚本在10.2.0.3上运行):
CREATE TABLE t AS SELECT ROWNUM ID FROM all_objects WHERE ROWNUM <= 100;
CREATE OR REPLACE PACKAGE cursor_pck AS
TYPE out_result_type is REF CURSOR;
PROCEDURE stored_proc (p_in IN NUMBER DEFAULT 10,
p_out_list IN OUT out_result_type);
END cursor_pck;
/
如果要同时选择并锁定行,可以使用FOR UPDATE
子句:
CREATE OR REPLACE PACKAGE BODY cursor_pck AS
PROCEDURE stored_proc (p_in IN NUMBER DEFAULT 10,
p_out_list IN OUT out_result_type) IS
BEGIN
OPEN p_out_list FOR SELECT a.id FROM t a WHERE ROWNUM <= p_in FOR UPDATE;
END stored_proc;
END cursor_pck;
/
通过以下设置,您将调用以下过程:
SQL> SET SERVEROUTPUT ON;
SQL> DECLARE
2 l_cursor cursor_pck.out_result_type;
3 l_id t.id%TYPE;
4 BEGIN
5 cursor_pck.stored_proc(3, l_cursor);
6 LOOP
7 FETCH l_cursor INTO l_id;
8 EXIT WHEN l_cursor%NOTFOUND;
9 dbms_output.put_line(l_id);
10 END LOOP;
11 END;
12 /
1
2
3
PL/SQL procedure successfully completed
答案 2 :(得分:0)
两个评论:
Type out_result_type is REF CURSOR;
,使用默认类型sys_refcursor。见这里:Oracle - How to have an out ref cursor parameter in a stored procedure? 答案 3 :(得分:0)
这不会按照它的编写方式工作,因为
out_list
需要游标,而不是游标结果。out_result_type
已用于类型,因此您无法将其重新定义为同一范围内的光标。答案 4 :(得分:0)
Oracle提供了一个预定义的弱引用游标:sys_refcursor。在使用中它看起来像:
CREATE OR REPLACE PACKAGE pkg_test
AS
PROCEDURE prc_cur (p_retval OUT sys_refcursor,
p_lookup IN VARCHAR2);
END pkg_test;
CREATE OR REPLACE PACKAGE BODY pkg_test
AS
PROCEDURE prc_cur(p_retval OUT sys_refcursor
p_lookup IN VARCHAR2)
IS
BEGIN
OPEN retval FOR SELECT a.value
FROM tblname a
WHERE a.id <= p_lookup;
END prc_cur;
END pkg_test;
这样可以省去需要声明类型的麻烦。 sys_refcursor是指向打开游标的结果集的指针。如果您熟悉Java,它与java.sql.ResultSet对象的概念相同,它提供了一种获取查询结果的方法。