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;