处理异常PLSQL时的程序流程
Posted
技术标签:
【中文标题】处理异常PLSQL时的程序流程【英文标题】:Program flow when handling exception PLSQL 【发布时间】:2012-04-19 21:04:55 【问题描述】:我的存储过程如下所示:
sqlQuery := 'DROP INDEX idArchivoIndex';
EXECUTE IMMEDIATE sqlQuery;
EXCEPTION --En caso de que no exista el índice capturamos la excepcion
WHEN index_not_exists THEN NULL; --y la ignoramos
sqlQuery := 'CREATE INDEX idArchivoIndex'||
' ON '||qusuario||' (id_archivo)';
EXECUTE IMMEDIATE sqlQuery;
doresetvalidacion(qusuario, idarchivo);
IF (tipoDependencia = 'PEC') THEN
dovalidapec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
COMMIT;
ELSIF (tipoDependencia = 'SAGARPA') THEN
dovalidacionpec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
COMMIT;
END IF;
如果没有引发异常,程序只会删除索引但不会重新创建索引!我以为这部分代码
EXCEPTION
WHEN index_not_exists THEN NULL;
处理了错误,然后继续下面的代码。现在我看到了结果,当且仅当引发异常时,EXCEPTION
被执行。
我想要的是简化我的代码,我不想在EXCEPTION
子句之前复制粘贴相同的代码块,只是为了让它按预期工作。有没有办法实现它?也许有一个嵌套的BEGIN ... END
块?还是我必须制定一个单独的程序来重用代码?
干杯。
更新
create or replace
PROCEDURE DOVALIDAINFORMACION
(
QARCHIVO IN VARCHAR2
, QUSUARIO IN VARCHAR2
, QANIOFISCAL IN VARCHAR2
) AS
imprimirMensajes CHAR;
tipoDependencia VARCHAR2(25);
idArchivo NUMBER;
sqlQuery VARCHAR2(100);
index_not_exists EXCEPTION;
PRAGMA EXCEPTION_INIT(index_not_exists, -1418);
BEGIN
sqlQuery := 'DROP INDEX idArchivoIndex';
EXECUTE IMMEDIATE sqlQuery;
----------------------
EXCEPTION --En caso de que no exista el índice capturamos la excepcion
WHEN index_not_exists THEN --y la ignoramos
NULL;
END;
----------------------
sqlQuery := 'CREATE INDEX idArchivoIndex'||
' ON '||qusuario||' (id_archivo)';
EXECUTE IMMEDIATE sqlQuery;
doresetvalidacion(qusuario, idarchivo);
IF (tipoDependencia = 'PEC') THEN
dovalidapec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
COMMIT;
ELSIF (tipoDependencia = 'SAGARPA') THEN
dovalidacionpec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
COMMIT;
END IF;
END DOVALIDAINFORMACION;
但无法编译程序。
Error(32,3): PLS-00103: Se ha encontrado el símbolo "SQLQUERY"
Error(33,48): PLS-00103: Se ha encontrado el símbolo ";" cuando se esperaba uno de los siguientes: ) , * & = - + < / > at in is mod remainder not rem <an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_ LIKE4_ LIKEC_ between || member SUBMULTISET_
【问题讨论】:
【参考方案1】:我怀疑您更新的代码中只是缺少一个额外的BEGIN
。 EXCEPTION
子句始终匹配 BEGIN
和 END
。在您发布的代码中,EXCEPTION
与过程的BEGIN
匹配。您需要它来匹配嵌套 PL/SQL 块的 BEGIN
。
create or replace
PROCEDURE DOVALIDAINFORMACION
(
QARCHIVO IN VARCHAR2
, QUSUARIO IN VARCHAR2
, QANIOFISCAL IN VARCHAR2
) AS
imprimirMensajes CHAR;
tipoDependencia VARCHAR2(25);
idArchivo NUMBER;
sqlQuery VARCHAR2(100);
index_not_exists EXCEPTION;
PRAGMA EXCEPTION_INIT(index_not_exists, -1418);
BEGIN
BEGIN
sqlQuery := 'DROP INDEX idArchivoIndex';
EXECUTE IMMEDIATE sqlQuery;
EXCEPTION --En caso de que no exista el índice capturamos la excepcion
WHEN index_not_exists THEN --y la ignoramos
NULL;
END;
sqlQuery := 'CREATE INDEX idArchivoIndex'||
' ON '||qusuario||' (id_archivo)';
EXECUTE IMMEDIATE sqlQuery;
doresetvalidacion(qusuario, idarchivo);
IF (tipoDependencia = 'PEC') THEN
dovalidapec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
COMMIT;
ELSIF (tipoDependencia = 'SAGARPA') THEN
dovalidacionpec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
COMMIT;
END IF;
END DOVALIDAINFORMACION;
顺便说一句,在 PL/SQL 块中删除然后立即重新创建索引似乎很奇怪。如果这与您关于recreating an index after a load 的问题有某种关系,恐怕您可能误解了我的回答。在我之前的回答中,我指出删除索引、加载 1000 万行数据然后重新创建索引可能更有效。假设加载发生在您在此代码中进行的存储过程调用中,您可能希望在加载完成后重新创建索引。
【讨论】:
好的。这解释了很多。我其实误会了。我必须纠正它。无论如何,假设出于某种原因我需要这样做。我用你的建议更新了我的问题,但有一些错误。 @BRabbit27 - 更新了我的答案。 谢谢!这就是我一直在寻找的。并在其他线程上遵循您的建议。以上是关于处理异常PLSQL时的程序流程的主要内容,如果未能解决你的问题,请参考以下文章