编译PL/SQL过程时由于BEGIN TRY和END CATCH语句导致的语法错误;



我有以下代码作为PL/SQL过程的一部分:

OPEN c1;
FETCH c1 INTO vr_usuario;
WHILE c1%found LOOP
BEGIN TRY
INSERT INTO users_unit_changes ( <--- Error 1 happens here
iduserunitchange,
nif,
inspectiondate,
workdate
) VALUES (
seq_userunitchanges.NEXTVAL,
vr_usuario.iddni,
v_fecha,
NULL
);


FETCH c1 INTO vr_usuario;
END TRY;
BEGIN CATCH
END CATCH; <--- Error 2 happens here
END LOOP;

我想实现的是,如果插入由于任何原因失败,则执行传递到c1游标上存在的以下行。

但是当我试图编译过程(错误发生的地方在代码上标记)时,我得到以下错误:

Error(34,9): PLS-00103: "INSERT"符号已找到,而期望的是下列符号之一::=。(@ %;符号" "已被"INSERT"继续。

Error(50,9): PLS-00103: "END"符号已找到,而期望的是下列符号之一::=。(@ %;符号" "已被"END"继续。

错误的原因是什么?

TRYCATCH是无效的PL/SQL语法

你想:

CREATE PROCEDURE procedure_name (
v_fecha    users_unit_changes.inspectiondate%TYPE DEFAULT SYSDATE
)
IS
CURSOR c1 IS
SELECT DUMMY AS iddni FROM DUAL;
vr_usuario C1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO vr_usuario;
EXIT WHEN c1%NOTFOUND;
BEGIN
INSERT INTO users_unit_changes (
iduserunitchange,
nif,
inspectiondate,
workdate
) VALUES (
seq_userunitchanges.NEXTVAL,
vr_usuario.iddni,
v_fecha,
NULL
);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN -- Name the exception to catch
-- Handle the exception
NULL;
END;
END LOOP;
END;
/

小提琴

您得到的错误与无效语法有关,正如您已经听到的。


考虑使用"simpler"游标FOR循环-有了它- Oracle为你做了大部分的工作-你不必声明游标变量,打开游标,从它获取,担心退出循环或关闭游标。

但是,您仍然需要一个内部BEGIN-EXCEPTION-END块,它将在发生错误时让循环继续。

DECLARE
-- just guessing; you didn't explain what V_FECHA is
v_fecha  users_unit_changes.inspectiondate%TYPE := SYSDATE;
BEGIN
FOR vr_usuario IN (SELECT iddni FROM your_table)
LOOP
BEGIN
INSERT INTO users_unit_changes (iduserunitchange,
nif,
inspectiondate,
workdate)
VALUES (seq_userunitchanges.NEXTVAL,
vr_usuario.iddni,
v_fecha,
NULL);
EXCEPTION
WHEN OTHERS
THEN
-- This ("OTHERS") handles any error that might happen. If you know which
-- errors you expect, handle them. I'm just displaying IDDNI that failed
-- and error which says *why* it failed
DBMS_OUTPUT.put_line (vr_usuario.iddni || ': ' || SQLERRM);
NULL;
END;
END LOOP;
END;


另一方面,循环通常是逐行处理的,它可能会很慢;如果可以的话,切换到设定加工。我不知道您可能期望的错误,但您可以尝试使用merge,看看会发生什么。如果它确实有效,对于大数据集,它应该比循环版本快得多。

MERGE INTO users_unit_changes a
USING table_that_contains_iddni b
ON (a.nif = b.iddni)
WHEN NOT MATCHED
THEN
INSERT     (iduserunitchange,
nif,
inspectiondate,
workdate)
VALUES (seq_userunitchanges.NEXTVAL,
b.iddni,
v_fecha, --> once again, I don't know what it is
NULL);

最新更新