【问题标题】:PL/SQL - Delete current record in FOR IN LOOPPL/SQL - 删除 FOR IN LOOP 中的当前记录
【发布时间】:2017-10-24 02:38:41
【问题描述】:

我想弄清楚如何使用 FOR .. IN .. LOOP 删除记录

FOR REC IN (SELECT * FROM WORKLIST) LOOP
  GET_DATA(REC);
  --DELETE REC FROM WORKLIST
END LOOP;

GET_DATA 过程将每一行分解为多个行,因此当前行已过时。我正在尝试仅删除当前记录。不确定在这种情况下是否可以使用 REC 对象。

很遗憾,WORKLIST 没有任何键。

【问题讨论】:

    标签: sql oracle plsql sql-delete for-in-loop


    【解决方案1】:

    如果 WORKLIST 有主键,只需使用它:

    DELETE FROM WORKLIST WHERE <PK> = REC.<PK>
    

    如果没有主键我会尝试:

    DECLARE
      vTmp schema.worklist%rowtype;
    BEGIN
      FOR rec IN (SELECT rowid, w.* FROM WORKLIST w) LOOP
        vTmp := null;
        vTmp.col1 := rec.col1;
        vTmp.col2 := rec.col2;
        -- And so on ...
        GET_DATE(vTmp);
        DELETE FROM WORKLIST WHERE rowid = rec.rowid;
      END LOOP;
    END;
    

    【讨论】:

    • 很遗憾,WORKLIST 没有任何键。
    • 哦,我喜欢这样,现在我在 GET_DATA(REC) 行上收到错误消息。错误:PLS-00306:调用“GET_DATA”时参数的数量或类型错误。该过程的定义如下: PROCEDURE GET_DATA(P_REC WWMT_WORKLIST%ROWTYPE) IS ... 有没有办法在该 ROWTYPE 中包含 ROWID?
    • 我看到了两个选项: 1) 在更广泛的范围内声明一个带有 rowid 的游标,并在两个过程中使用这种游标的行类型。 2) 使用 WORKLIST%ROWTYPE 变量并将所有列值 - 除了 rowid - 从当前记录复制到变量。所以你将把变量传递给过程。
    • 我将如何进行选项 2?我对此并不熟悉。
    【解决方案2】:

    在光标上使用current of

    DECLARE
    CURSOR c1 IS 
        SELECT * from worklist FOR UPDATE <any column name>; 
    BEGIN 
          open c1; 
          loop 
              fetch c1 into crow; 
              exit when c1%notfound;  
              DELETE FROM worklist WHERE CURRENT OF c1; 
          end loop;        
          COMMIT; 
          close c1; 
    END;
    

    【讨论】:

    • For Update 通常不受欢迎。这可能会导致死锁。在此处阅读更多信息asktom.oracle.com/pls/asktom/…
    • @XING - 我认为您误解了 Tom Kyte 的回复。 FOR UPDATE 允许我们实现一个悲观的锁定策略,避免死锁。
    • @APC。在前面的部分中,它还表明FOR UPDATE 导致了死锁。我指的是正确的。请参考整篇文章
    • @XING - 那是deadlock detected,这会导致第二次尝试的事务失败。这就是我们想要发生的事情。如果没有 FOR UPDATE,两个会话都会失败。
    • @APC。这就是我所说的。 FOR UPDATE 会导致死锁。你在哪里找到我穿在这里。这就是为什么他提到了一个自治事务的例子。
    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多