我有很多使用T-SQL的经验,但我是PL / SQL的新手。
我的循环下面有什么问题?
简单的事情......我有一个带有OUT光标参数的SP 我只是想调用它并打印出该OUT参数中返回的记录。
但我得到的错误是:
'CC'不是程序或未定义
DECLARE
cc SYS_REFCURSOR;
BEGIN
TEST_001
(
CUR => cc,
d => 1
);
DBMS_OUTPUT.put_line('DONE');
FOR rec in cc
LOOP
dbms_output.put_line(rec.OK);
END LOOP;
END;
如果我评论我的FOR
循环,那么它可以正常工作,
但是我无法从SP中看到我从光标中得到的东西。
答案 0 :(得分:3)
您的cc
是引用光标,与标准光标不同。您不能将for <record> in <cursor> loop
构造与ref游标一起使用。
您需要从ref游标中获取正确数据类型的变量(或多个变量,具体取决于过程中的游标查询的内容),您可以在循环中执行,当结果集从引用光标已用尽:
DECLARE
cc SYS_REFCURSOR;
result VARCHAR2(10); -- or whatever is appropriate
BEGIN
TEST_001
(
CUR => cc,
d => 1
);
LOOP
FETCH cc INTO result;
EXIT WHEN cc%NOTFOUND;
dbms_output.put_line(result);
END LOOP;
END;
/
我使用了一个result
变量并猜到了数据类型;在实际查询中,每个列表达式都需要一个。或者,您可以定义每列表达一个字段的记录类型;如果游标查询有两个:
DECLARE
cc SYS_REFCURSOR;
TYPE rec_type IS RECORD (
ok VARCHAR2(10), -- or whatever is appropriate
other NUMBER -- or whatever is appropriate
);
rec rec_type;
BEGIN
TEST_001
(
CUR => cc,
d => 1
);
DBMS_OUTPUT.put_line('DONE');
LOOP
FETCH cc INTO rec;
EXIT WHEN cc%NOTFOUND;
dbms_output.put_line(rec.ok);
END LOOP;
END;
/
如果光标查询从单个表中执行select *
,您也可以使用其%ROWTYPE
而不是定义自己的记录类型。
如果您事先不知道引用游标中的结构,那么您将进入动态SQL和dbms_sql
包的世界,这更加复杂。