使用 FETCH 的 PL/SQL 游标 FOR 循环

Posted

技术标签:

【中文标题】使用 FETCH 的 PL/SQL 游标 FOR 循环【英文标题】:PL/SQL Cursor FOR loop using FETCH 【发布时间】:2015-04-21 00:04:39 【问题描述】:

我正在尝试帮助我的朋友完成 Oracle 作业,但他遇到了以下问题:

如果博客 id 小于 4,则使用游标 FOR 循环检索博客 ID、博客 url 和博客描述,并将其放在游标变量中。获取并处理每条记录,并在表日志中为返回的每个博客 id 插入一行。

我们发现很难理解,但我们有查询:

DECLARE
    CURSOR blog_cursor IS SELECT * FROM blog;
BEGIN
  FOR blog_item IN blog_cursor LOOP
    IF( blog_item.blog_id > 4 ) THEN
      -- Insert a row in the "table log"
      INSERT INTO log( log_id, log_url, log_desc )
      VALUES( blog_item.blog_id, blog_item.blog_url, blog_item.blog_desc );
    END IF;
  END LOOP;
END;
/

表:

blog
    blog_id
    blog_url
    blog_desc

查询完成了这项工作,但它不使用 FETCH 关键字,因此我们认为它在技术上不正确。这个问题似乎写得不好,但是您将如何使用 FETCH 关键字来回答它?我是 PL/SQL 新手,但我有使用 SQL 的经验。

【问题讨论】:

INSERT INTO log( log_id, log_url, log_desc ) SELECT blog_id, blog_url, blog_desc FROM blog WHERE blog_id > 4; 似乎比使用游标简单得多——尽管它也不使用FETCH 我同意,这门课程的老师似乎很懒惰。 【参考方案1】:

你做对了,你不需要获取,事实上你做了获取,但你隐式地做了,要使用 fetch 关键字你需要一个 record 类型,你还需要打开和关闭游标并检查它是否打开并检查它是否有行(在循环中),以下是另一个使用 fetch 和记录类型的游标:

DECLARE
    CURSOR blog_cursor IS SELECT * FROM blog;
    blog_item blog%rowtype;
BEGIN
  OPEN blog_cursor;
  LOOP
    FETCH blog_cursor INTO blog_item;
    EXIT WHEN blog_cursor%NOTFOUND;
    IF( blog_item.blog_id > 4 ) THEN
      -- Insert a row in the "table log"
      INSERT INTO log( log_id, log_url, log_desc )
      VALUES( blog_item.blog_id, blog_item.blog_url, blog_item.blog_desc );
    END IF;
  END LOOP;
  CLOSE blog_cursor;
END;

【讨论】:

啊,这真的很有帮助,谢谢。也许如果它是隐含的,那么它毕竟是正确的答案。让我们感到困惑的另一件事是,下一个问题是专门创建一个“基于表的记录游标”。稍后我可能会发布另一个关于该问题的问题。 不客气,在你的游标中你也不能声明任何游标,我的意思是你可以在 (...) 中使用游标的查询而不是游标的名称,无论如何,它是还可以看看隐式和显式游标。祝你好运。 在代码中,插入是只运行一次还是会为满足条件的每一行运行多次插入?

以上是关于使用 FETCH 的 PL/SQL 游标 FOR 循环的主要内容,如果未能解决你的问题,请参考以下文章

pl / sql如何使用带有游标的for循环进行更新操作

PL/SQL 04 游标 cursor

PL/SQL 没有发现游标的数据异常

Pl/Sql 在for循环中打开游标

在PL/SQL中使用游标动态sql和绑定变量的小例子

PL/SQL:游标使用中的 ORA-01001