循环中的 PL/SQL 异常

Posted

技术标签:

【中文标题】循环中的 PL/SQL 异常【英文标题】:PL/SQL exception in loop 【发布时间】:2015-01-20 13:57:22 【问题描述】:

我在数据库中有这 3 个表: - 人 - 事物 - 类别

“类别”表是新的,所以我必须编写一个脚本来迁移数据。以前一个人可以有很多东西……现在一个人可以有很多类别,每个类别可以有很多东西。

所以我必须编写一个脚本来遍历事物并检查是否已经为事物和人创建了一个组,如果没有,则创建它并更新事物数据。如果已创建类别,只需更新事物数据即可。

declare
    -- thing
    v_thing_id thing.id%TYPE;
    v_thing_person_id thing.person_id%TYPE;
    v_thing_category_name thing.category_name%TYPE;
    v_thing_category_id thing.category_id%TYPE;

    -- category_name
    v_category_id category.id%TYPE;

    cursor c_thing_ids is
        select b.id
        from thing b
        where category_id is null
    ;

begin
    open c_thing_ids;

    loop
        -- iterate all the thing ids
        fetch c_thing_ids into v_thing_id;

        exit when c_thing_ids%NOTFOUND;

        -- look for already created category for current thing
        select e.id
        into v_category_name_id
        from category e
        where e.person_id = v_thing_person_id
        and e.category_name = v_thing_category_name;

        -- if exists: update thing
        if v_category_name_id is not null then
            update thing
                set category_id = v_category_name_id
                where id = v_thing_id;
        else
        -- if not: create category and update thing
            insert into category (id, category_name)
                values (HIBERNATE_SEQUENCE.NEXTVAL,  v_thing_category_name);
            select e.id
                into v_category_name_id
                from category e
                where e.person_id = v_thing_person_id
                and e.category_name = v_thing_category_name;
            update thing
                set category_id = v_category_name_id
                where id = v_thing_id;
        end if; 
    end loop;
end;

我不是 PL/SQL 专家,事实上这是我“在现实生活中”使用它做的第二件事,所以,正如预期的那样,我得到一个错误:ORA-01403 in line:

select e.id
    into v_category_name_id
    from category e
    where e.person_id = v_thing_person_id
    and e.category_name = v_thing_category_name;

我应该如何处理?我在 no_data_found 时尝试了异常,但随后它抱怨异常不在正确的位置...

【问题讨论】:

【参考方案1】:

这应该可以解决问题:

-- look for already created category for current thing
begin 
  select e.id
      into v_category_name_id
      from category e
      where e.person_id = v_thing_person_id
      and e.category_name = v_thing_category_name;
exception when no_data_found then
  v_category_name_id := null;
end;

【讨论】:

是的,就是这样,我忘了在循环中使用开始/结束。使用它我可以声明一个异常块。

以上是关于循环中的 PL/SQL 异常的主要内容,如果未能解决你的问题,请参考以下文章

如何以不同的方式处理 PL/SQL 中的不同异常?

Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器

PL/SQL 编程基础,变量,分支,循环,异常

Oracle PL/SQL 在循环中捕获锁定异常并继续

即使在 PL/SQL 中发生异常,也继续循环读取 excel 行

PL/SQL 过程中的异常处理