更新Cursor For循环中的列

时间:2014-06-06 15:13:05

标签: plsql oracle11g oracle-sqldeveloper

我正在运行一个CURSOR FOR LOOP,而我正在尝试做的事情之一是更新每个记录的列,以及循环运行的日期。我在循环中包含了以下语句

UPDATE SALES_TABLE
SET SETTLEMENTDATE = SYSDATE
WHERE RECEIPTNO= R1.RECEIPTNO;

在这种情况下,RECEIPTNO是一个PK,如果这有任何区别。知道我做错了什么吗? SETTLEMENTDATE列保持为NULL。

更大的环状可见性更新

FOR R1 IN c_dbfData LOOP

...

UPDATE SALES_TABLE
SET SETTLED = 'Y'
WHERE RECEIPTNO = R1.RECEIPTNO;

UPDATE SALES_TABLE
SET SETTLEMENTDATE = SYSDATE
WHERE RECEIPTNO= R1.RECEIPTNO;

END LOOP;

我用省略号排除的只是写入一个文件,工作正常。

2 个答案:

答案 0 :(得分:2)

我建议您按如下方式修改代码:

DBMS_OUTPUT.PUT_LINE('Entering update loop');

DECLARE
  nRows_read  NUMBER := 0;
BEGIN
  FOR R1 IN c_dbfData LOOP
    nRows_read := nRows_read + 1;

    DBMS_OUTPUT.PUT_LINE('In loop, R1.RECEIPTNO=' || R1.RECEIPTNO);

    BEGIN
       ...  -- put your file logic here
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Error in file logic: SQLCODE=' || SQLCODE ||
                           '  SQLERRM=' || SQLERRM);
        RAISE;
    END;

    BEGIN
      UPDATE SALES_TABLE
        SET SETTLED = 'Y'
        WHERE RECEIPTNO = R1.RECEIPTNO;

      DBMS_OUTPUT.PUT_LINE('  First update successful for RECEIPTNO=' ||
                           R1.RECEIPTNO ||  
                           ', ' || SQL%ROWCOUNT || ' rows updated');
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Error in first UPDATE for RECEIPTNO=' ||
                             R1.RECEIPTNO || ': SQLCODE=' || SQLCODE ||
                             '  SQLERRM=' || SQLERRM);
        RAISE;
    END;

    BEGIN
      UPDATE SALES_TABLE
        SET SETTLEMENTDATE = SYSDATE
        WHERE RECEIPTNO= R1.RECEIPTNO;

      DBMS_OUTPUT.PUT_LINE('  Second update successful for RECEIPTNO=' ||
                           R1.RECEIPTNO ||  
                           ', ' || SQL%ROWCOUNT || ' rows updated');
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Error in second UPDATE for RECEIPTNO=' ||
                             R1.RECEIPTNO || ': SQLCODE=' || SQLCODE ||
                             '  SQLERRM=' || SQLERRM);
        RAISE;
    END;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('Update loop complete, ' || nRows_read || ' rows read');
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error caught in outer handler after ' || nRows_read ||
                         'rows: SQLCODE=' || SQLCODE ||
                         '  SQLERRM=' || SQLERRM');
    RAISE;
END;

然后从上面检查DBMS_OUTPUT。理想情况下,您应该看到已处理的RECEIPTNO列表,以及每次更新的行,注意更新更改了多少行。

或者,如果您正在使用PL / SQL Developer之类的工具,它可以轻松访问Oracle PL / SQL调试器,您可以省略内部PUT_LINE,只需在EXCEPTION块中的PUT_LINE调用上设置断点,然后在调试器下运行您的过程,看它是否遇到任何一个断点。

分享并享受。

答案 1 :(得分:0)

我对提交逻辑没有问题,必须使用where子句(RECEIPTNO = R1.RECEIPTNO)关闭。 R1.RECEIPTNO不包含您期望的值,或者没有按预期填充表sales_table。

一般来说: - 它会快两倍,将两个更新组合起来就是你的例子 - 如果你可以在没有程序循环的单个语句中更新,那就更快了