首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PL/SQL在for循环内执行即时异常处理

PL/SQL在for循环内执行即时异常处理
EN

Stack Overflow用户
提问于 2012-11-21 12:02:57
回答 1查看 10.8K关注 0票数 2

在下面的PL/SQL代码中,TABLE_ONE包含表名tname、列名cname和rowid rid。For循环从TABLE_ONE获取记录,并更新表tname中具有行id rid的记录的列cname。但是,如果要在tname中更新的记录被锁定,那么for循环就会停滞,并且不会处理来自TABLE_ONE的更多记录。理想情况下,忽略更新失败的记录并继续执行的脚本。请告诉我什么可能是问题。

代码语言:javascript
复制
BEGIN
    FOR c IN (SELECT * FROM TABLE_ONE a )
    LOOP
        DECLARE
            TNAME varchar2(30);
            CNAME varchar2(30);
            RID ROWID;
            X number;
            updt_stmt varchar2(300);
        BEGIN
          BEGIN
            TNAME := c.TNAME;
            CNAME := c.CNAME;
            RID   := c.RID;                
            DBMS_OUTPUT.PUT_LINE( TNAME || '=>' || CNAME);
            updt_stmt := 'UPDATE ' || TNAME || ' SET ' || CNAME || ' = ''123'' WHERE  ROWID   like ''%' || RID || '%''';                
            EXECUTE IMMEDIATE updt_stmt;

          EXCEPTION
            WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('ERROR');

          END;
        END;
    END LOOP;
END;
EN

回答 1

Stack Overflow用户

发布于 2017-09-09 02:24:37

未测试,但我认为您可以首先尝试使用FOR UPDATE锁定记录,并在其他事务处于活动状态时指定NOWAIT导致失败。然后,您可以捕获此异常并跳过处理。下面是一个未经测试的示例:

代码语言:javascript
复制
DECLARE
  x ROWID;
  resource_busy EXCEPTION;
  PRAGMA EXCEPTION_INIT(resource_busy,
                        -00054);
BEGIN
  FOR c IN (SELECT *
              FROM table_one a)
  LOOP
    DECLARE
      tname     VARCHAR2(30);
      cname     VARCHAR2(30);
      rid       ROWID;
      x         NUMBER;
      updt_stmt VARCHAR2(300);
    BEGIN
      BEGIN
        tname := c.tname;
        cname := c.cname;
        rid   := c.rid;
        dbms_output.put_line(tname || '=>' || cname);

        BEGIN
          EXECUTE IMMEDIATE 'SELECT rowid FROM ' || tname ||
                            ' WHERE rowid = :x FOR UPDATE NOWAIT'
            INTO x
            USING rid;
        EXCEPTION
          WHEN resource_busy THEN
            dbms_output.put_line('Record locked; try again later.');
            CONTINUE;
        END;

        updt_stmt := 'UPDATE ' || tname || ' SET ' || cname ||
                     ' = ''123'' WHERE  ROWID   like ''%' || rid || '%''';
        EXECUTE IMMEDIATE updt_stmt;

      EXCEPTION
        WHEN OTHERS THEN
          dbms_output.put_line('ERROR');

      END;
    END;
  END LOOP;
END;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13486156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档