暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 游标内部的数据更改

ASKTOM 2021-03-17
663

问题描述

嗨,汤姆,
我的问题是关于更改和提交函数中的一些数据,如果这是一种 “推荐” 的方式,或者如何以更好的方式做到这一点。
我有一个带有光标和循环的函数,在循环内部,我们根据循环条件更改了一些数据。

DDL就像:
FUNCTION ProcessMessages (ParBusyLastProcessing    OUT INTEGER,
                          ParErrorText             OUT VARCHAR2)
RETURN INTEGER
IS
  ConstFunction CONSTANT VARCHAR2(40) := 'ProcessMessages';
  LocRc                   INTEGER;
  LocInfoText             VARCHAR2(2000);
  LocCountUnprocessedMsg  INTEGER;
BEGIN
  LocRc           := 0;
  LocInfoText     := ' ';
  ParErrorText    := ' ';
  ParBusyLastProcessing := 21;

  FOR CrsSearchNewMsg IN (SELECT NaId
                            FROM NaInfoSapToWlt
                           WHERE Status = 2001 
                             AND NaArt  = MSGTYPE_PROCESS_ORDER
                           ORDER BY NaId)
  LOOP
    -- Check if there are any unprocessed messages,
    -- that have to be processed first 
    LocInfoText := 'SELECT COUNT(*) FROM NaInfoSapToWlt';
    SELECT COUNT(*)
      INTO LocCountUnprocessedMsg
      FROM NaInfoSapToWlt
     WHERE NaArt  <> MSGTYPE_PROCESS_ORDER
       AND Status <> 2004
       AND NaId    < CrsSearchNewMsg.NaId;

    -- If so then exit loop
    IF LocCountUnprocessedMsg > 0
    THEN
      EXIT; -- LOOP
    ELSE
      -- Continue processing
      ParBusyLastProcessing := 21;
    END IF;

    -- Call ERP proessing function
    IF LocRc = 0
    THEN
      LocRc := KP2PASX.Neue_Nachricht ( ParNaId => CrsSearchNewMsg.NaId,
                                        ParText => ParErrorText);
    END IF;
    
    IF LocRc <> 0
    THEN
      -- Rollback processing
      ROLLBACK;
      -- Set status to error
      UPDATE NaInfoSapToWlt
         SET Status     = 2004
           , Fehlertext = SUBSTR(ParErrorText, 1, 256)
       WHERE NaId = CrsSearchNewMsg.NaId;
    END IF;

    -- Reset RC
    LocRc := 0;
    -- Commit status change
    COMMIT;

  END LOOP;

  RETURN LocRc;

EXCEPTION
  WHEN OTHERS THEN
    TRACEHDL.TrcException(ParPackage      => ConstPackageName,
                          ParFunction     => ConstFunction,
                          ParStatement    => LocInfoText,
                          ParMeldungstext => TO_CHAR(SQLCODE) || ' ' || SQLERRM);
    TRACEHDL.TrcEndFunction;

    ParErrorText := GetOraErrorText(ConstPackageName||'.'||ConstFunction||' '||LocInfoText);
    LocRc := -1;
    RETURN LocRC;
END ProcessMessages;


如第16行所示,我们从表NaInfoSapToWlt中查询数据,并在第52行中更新所选行的状态并提交更改。

您是否希望以这种方式进行操作有任何问题,或者这是一种支持和推荐的方式?

专家解答

我希望这里会发生几件事:

-该过程需要很长时间才能完成
-您会遇到数据一致性问题,并可能ORA-01555错误

所以我会not建议这样做。

best编写快速SQL的方法是执行一个更改的更新all行。这就是它的设计目的!

理想情况下,您将使用驱动for循环的查询,并在更新的where子句中使用它。由于这里还有其他各种事情,因此可能需要使用批量处理。

https://blogs.oracle.com/oraclemagazine/bulk-processing-with-bulk-collect-and-forall
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论