现在我正在将数据导入并转换为Oracle数据库,如下所示:
程序定期轮询特定文件夹,一旦找到文件,它就会执行一个批处理文件,该文件在Python&amp ;; bash然后调用SQL * Loader将CSV文件加载到临时表中。
然后,批处理脚本调用SQL脚本(通过SQLPlus)进行最终转换,并将转换后的数据插入到各自的临时表的主表中。
此方法的问题是SQLPlus端没有错误处理,例如。如果'insert into'语句因违反约束(或任何其他原因)而失败,它仍将继续执行SQL脚本中包含的其余语句。
理想情况下,如果发生任何异常,我希望回滚所有更改,并将异常的详细信息插入到etl日志表中。
存储过程似乎非常适合,因为异常处理是内置的。但是,我正在努力学习语法 - 特别是我如何能够使用我的大型SQL脚本(它只是INSERT INTO,UPDATE,CREATE,DROP,DELETE等语句的组合)并将它们放入存储过程中。基本错误处理。
我希望的是:
关于我的尝试 - 我已经尝试将部分SQL脚本复制到存储过程中,但它们始终无法编译错误'PLS-00103在遇到以下某个时遇到符号'。例如
CREATE OR REPLACE PROCEDURE ETL_2618A AS
BEGIN
DROP SEQUENCE "METER_REPORTING"."SEQ_2618";
CREATE SEQUENCE SEQ_2618;
END ETL_2618A;
Oracle文档并不是非常容易访问,而且谷歌搜索/搜索StackOverflow我没有太多运气,但如果我错过了一些明显的东西,我会道歉。
答案 0 :(得分:3)
要在PL / SQL中执行DDL,您需要使用动态sql。
CREATE OR REPLACE PROCEDURE testProc IS
s_sql VARCHAR2(500);
BEGIN
s_sql := 'DROP SEQUENCE "METER_REPORTING"."SEQ_2618"';
EXECUTE IMMEDIATE s_sql;
s_sql := 'CREATE SEQUENCE "METER_REPORTING"."SEQ_2618"';
EXECUTE IMMEDIATE s_sql;
EXCEPTION
WHEN OTHERS THEN
NULL;
end testProc;
/
答案 1 :(得分:0)
如果您在sqlplus中运行脚本,则可以使用:
每当sqlerror
控制发生错误时应该发生的事情。
http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12052.htm
答案 2 :(得分:0)
向PL / SQL proc或脚本添加异常处理并不困难,但当然需要进行一些编码。在这里,您的程序略微打扮,并添加了一些非常基本的错误报告:
CREATE OR REPLACE PROCEDURE ETL_2618A AS
nCheckpoint NUMBER;
BEGIN
nCheckpoint := 1;
EXECUTE IMMEDIATE 'DROP SEQUENCE "METER_REPORTING"."SEQ_2618"';
nCheckpoint := 2;
EXECUTE IMMEDIATE 'CREATE SEQUENCE SEQ_2618';
RETURN;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ETL_2618A failed at checkpoint ' || nCheckpoint ||
' with error ' || SQLCODE || ' : ' || SQLERRM);
RAISE;
END ETL_2618A;
未在动物身上进行测试 - 您将成为第一个! : - )