PLSQL DML операторы внутри процедуры

Я пытаюсь выполнить процедуру ниже, но он говорит мне использовать BULKCOLLECT и FORALL для рефакторинга моего кода. Это просто предупреждение или я не должен использовать, как показано ниже для моей процедуры. Если так, как я должен изменить код, поскольку я перебираю массив, и мне нужно, чтобы каждое значение обновлялось в таблицу.

CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE 
(
FILEARRAY IN STRARRAY,
DUPARRAY OUT STRARRAY,
PASSARRAY OUT STRARRAY,
FAILARRAY OUT STRARRAY,
MISSARRAY OUT STRARRAY
)

IS
dupCount NUMBER;
staCode    VARCHAR2 (10);
fileName VARCHAR2 (50);
dupfileName VARCHAR2(50);
fileId NUMBER;
ID VARCHAR2(20);
BEGIN
for i in 1 .. FILEARRAY.count
   loop
     fileName := FILEARRAY(i);


     SELECT COUNT (T.FILEID), T.FILEID,T.STATUS,T.ID INTO dupCount,fileId,staCode,ID FROM TB_TABLE_NAME T, TB_TABLE_NAME S
     WHERE T.FILEID=S.FILEID
     AND T.STATUS=S.STATUS
     AND T.FILENAME = fileName AND T.STATUS IN ('PASS', 'FAIL)
     GROUP BY T.FILEID,T.STATUS,T.ID;


     IF dupCount>1
     THEN 
     SELECT FILENAME INTO dupfileName FROM TB_TABLE_1
     WHERE STATUS IN ('PASS','FAIL') AND FILEID=fileId
     AND FILENAME != fileName;
     DBMS_OUTPUT.PUT_LINE(dupfileName);

     UPDATE TB_TABLE_1 SET STATUS='DUP' WHERE FILENAME=dupfileName;
     DUPARRAY(DUPARRAY.LAST +1 ) :=dupfileName;
     DBMS_OUTPUT.PUT_LINE(dupfileName);
     END IF;

     IF staCode = 'FAIL'
     THEN
     FAILARRAY(FAILARRAY.LAST+1) :=fileName;
     ELSIF staCode = 'PASS'
     THEN
     PASSARRAY(PASSARRAY.LAST+1) :=fileName;
     END IF;

   end loop;


EXCEPTION
    WHEN NO_DATA_FOUND THEN
    staCode :=NULL;
    MISSARRAY(MISSARRAY.LAST +1 ) :=fileName;
    WHEN OTHERS THEN
        PR_ERRORS('PR_VALIDATE', SQLERRM);
       ROLLBACK;

END;

/

1 ответ

Как я уже упоминал в комментарии, FORALL здесь находится вне контекста, поскольку здесь включена бизнес-логика, но снова вы можете попробовать BULK COLLECT с циклом FOR для итерации. Но объем данных не так велик, вы все равно можете пойти с построчным подходом. Надеюсь ниже поможет фрагмент. Также отсутствовали некоторые одиночные кавычки, которые привели бы к ошибке времени компиляции.

CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE(
    FILEARRAY IN STRARRAY,
    DUPARRAY OUT STRARRAY,
    PASSARRAY OUT STRARRAY,
    FAILARRAY OUT STRARRAY,
    MISSARRAY OUT STRARRAY )
IS
  dupCount    NUMBER;
  staCode     VARCHAR2 (10);
  fileName    VARCHAR2 (50);
  dupfileName VARCHAR2(50);
  fileId      NUMBER;
  ID          VARCHAR2(20);
BEGIN
  FOR i IN 1 .. FILEARRAY.count
  LOOP
    fileName := FILEARRAY(i);
    SELECT COUNT (T.FILEID),
      T.FILEID,
      T.STATUS,
      T.ID
    INTO dupCount,
      fileId,
      staCode,
      ID
    FROM TB_TABLE_NAME T,
      TB_TABLE_NAME S
    WHERE T.FILEID =S.FILEID
    AND T.STATUS   =S.STATUS
    AND T.FILENAME = fileName
    AND T.STATUS  IN ('PASS', 'FAIL')
    GROUP BY T.FILEID,
      T.STATUS,
      T.ID;
    IF dupCount>1 THEN
      SELECT FILENAME
      INTO dupfileName
      FROM TB_TABLE_1
      WHERE STATUS IN ('PASS','FAIL')
      AND FILEID    =fileId
      AND FILENAME != fileName;
      DBMS_OUTPUT.PUT_LINE(dupfileName);

      UPDATE TB_TABLE_1 
      SET STATUS='DUP' 
      WHERE FILENAME=dupfileName;

      DUPARRAY(DUPARRAY.LAST +1 ) :=dupfileName;
      DBMS_OUTPUT.PUT_LINE(dupfileName);
    END IF;

    IF staCode                     = 'FAIL' THEN
      FAILARRAY(FAILARRAY.LAST+1) :=fileName;
    ELSIF staCode                  = 'PASS' THEN
      PASSARRAY(PASSARRAY.LAST+1) :=fileName;
    END IF;
  END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
  staCode                       :=NULL;
  MISSARRAY(MISSARRAY.LAST +1 ) :=fileName;
WHEN OTHERS THEN
  PR_ERRORS('PR_VALIDATE', SQLERRM);
  ROLLBACK;
END;
Другие вопросы по тегам