在 PL/SQL 存储过程中声明游标

Posted

技术标签:

【中文标题】在 PL/SQL 存储过程中声明游标【英文标题】:Declaring cursor in a PL/SQL stored procedure 【发布时间】:2020-07-10 15:06:46 【问题描述】:

printf('local_time_greeting');

在使用 SQL Developer 运行存储过程时遇到了一些问题。下面是一个与前几行完全相同的示例,出于安全原因更改了变量名称。

CREATE OR REPLACE PROCEDURE redacted ( an_in_variable IN VARCHAR ) AS
    these VARCHAR;
    variables VARCHAR;
    don_apostrophe_t INT;
    matter INT;
BEGIN

DECLARE cursor_giving_me_trouble CURSOR FOR
SELECT something FROM db.table WHERE condition_1 = condition_2;
...

在编辑器中,SELECT 字是红色波浪线,当我尝试运行代码时,输​​出返回

PLS-00103: Encountered symbol "FOR" when expecting one of the following     := . ( @ % ; not null range default character

有什么想法吗?

【问题讨论】:

IS,而不是FOR。 Documentation. @AlexPoole 不幸返回同样的错误 部分的顺序是相反的。应该是 DECLARE ... BEGIN。 DECLARE 需要自己的 BEGIN/END,这可能已经在 ... 中了;但在显示的 existing BEGIN 之前不应该有 DECLARE - 主过程块的变量声明是可以的(除了数据类型......)。 RTFM 【参考方案1】:

您需要使用IS 而不是FOR,但是您的定义中的条款也有错误的顺序:

DECLARE
  CURSOR cursor_giving_me_trouble IS
    SELECT something FROM db.table WHERE condition_1 = condition_2;

db<>fiddle 仍然会出错,因为您的混淆代码中存在非法对象名称,但不是来自语法;和more complete example。

您也有可能尝试使用该构造:

FOR cursor_giving_me_trouble IN (
    SELECT something FROM db.table WHERE condition_1 = condition_2
) LOOP
...

而不是一个子块(一个新的声明,后跟开始/结束),其中仅引用游标。 db<>fiddle.

【讨论】:

【参考方案2】:

让您开始:

create or replace procedure redacted
    ( an_in_variable in varchar2 )
as
    these varchar2(123);
    variables varchar2(456);
    don_apostrophe_t integer;
    matter integer;
    cursor cursor_giving_me_trouble is
        select 'Welcome to PL/SQL' as whatever from dual where 1=1;
begin
    for r in cursor_giving_me_trouble loop
        dbms_output.put_line(r.whatever);
    end loop;
end;

但是,您通常不需要单独的游标定义,因为有这种紧凑的语法:

create or replace procedure redacted
    ( an_in_variable in varchar2 )
as
    these varchar2(123);
    variables varchar2(456);
    don_apostrophe_t integer;
    matter integer;
begin
    for r in (
        select 'Welcome to PL/SQL' as whatever from dual where 1=1
    )
    loop
        dbms_output.put_line(r.whatever);
    end loop;
end;

【讨论】:

以上是关于在 PL/SQL 存储过程中声明游标的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 打印出存储过程返回的引用游标

从存储过程中调用 PL/SQL 游标得到结果

oracle(sql)基础篇系列——PLSQL游标存储过程触发器

Oracle --- 存储过程函数包游标触发器

Oracle --- 存储过程函数包游标触发器

Oracle --- 存储过程函数包游标触发器