Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql oracle中的错误/异常处理_Sql_Oracle_Error Handling_Plsql - Fatal编程技术网

Sql oracle中的错误/异常处理

Sql oracle中的错误/异常处理,sql,oracle,error-handling,plsql,Sql,Oracle,Error Handling,Plsql,我想为下面的场景开发一个程序 我有一个源、一个目标和一个错误表。目标表和错误表具有源表中存在的所有字段。但是错误表的所有字段的数据类型都是varchar。错误表没有完整性、外键和其他约束。 错误表还有两个字段:错误号和错误消息 现在,当执行该过程时,若在将任何记录插入目标时出现错误,那个么该记录应该被移动到错误表中。此外,数据库错误代码和错误消息也应记录在错误表字段中,如前所述 我怎样才能制定这样的程序 表架构示例: source table src(id number

我想为下面的场景开发一个程序

我有一个源、一个目标和一个错误表。目标表和错误表具有源表中存在的所有字段。但是错误表的所有字段的数据类型都是varchar。错误表没有完整性、外键和其他约束。 错误表还有两个字段:错误号和错误消息

现在,当执行该过程时,若在将任何记录插入目标时出现错误,那个么该记录应该被移动到错误表中。此外,数据库错误代码和错误消息也应记录在错误表字段中,如前所述

我怎样才能制定这样的程序

表架构示例:

source table  
    src(id number 
        ,name varchar2(20)  
        , ... )

target table  
    tgt(id number 
        ,name varchar2(20) not null 
        , ... )

error table  
    err (id varchar2(255) 
          ,name  varchar2(255)
          , ... 
          , errno varchar2(255)
          , errmsg varchar2(255))

您看过Oracle自己的错误记录功能吗


您看过Oracle自己的错误记录功能吗


执行此操作的过程可能如下所示:

procedure ins_tgt(p_id in number, p_name in varchar2, ...) is
  v_errno number; v_errmsg varchar2(2000);
begin
  insert into tgt(id, name, ...) values (p_id, p_name, ...);
exception
  when others then
    /* copy sqlcode and sqlerrm into variables since they can't be used directly in a SQL statement */
    v_errno := sqlcode;
    v_errmsg := sqlerrm;
    insert into err(id, name, errno, errmsg) values (p_id, p_name, v_errno, v_errmsg);
end;


procedure copy_src_tgt is
begin
  for s in (select * from src) loop
    ins_tgt(s.id, s.name, ...);
  end loop;
end;

但是,将数据从一个表复制到另一个表似乎是一种非常低效的方法…

执行此操作的过程可能如下所示:

procedure ins_tgt(p_id in number, p_name in varchar2, ...) is
  v_errno number; v_errmsg varchar2(2000);
begin
  insert into tgt(id, name, ...) values (p_id, p_name, ...);
exception
  when others then
    /* copy sqlcode and sqlerrm into variables since they can't be used directly in a SQL statement */
    v_errno := sqlcode;
    v_errmsg := sqlerrm;
    insert into err(id, name, errno, errmsg) values (p_id, p_name, v_errno, v_errmsg);
end;


procedure copy_src_tgt is
begin
  for s in (select * from src) loop
    ins_tgt(s.id, s.name, ...);
  end loop;
end;
CREATE OR REPLACE PACKAGE BODY foo_dml IS

    PROCEDURE log_err (
        p_sqlcode IN NUMBER,
        p_sqlerrm IN VARCHAR2,
        p_src     IN foo%ROWTYPE
    ) IS
        -- inserts the input row to the err log
    BEGIN
        INSERT INTO err (
            errno,
            errmsg,
            ID,
            NAME,
            ...
        ) VALUES (
            p_sqlcode,
            p_sqlerrm,
            p_src.id,
            p_src.name,
            ...
        );
    END;

    PROCEDURE copy_to_tgt (
        p_src IN foo%ROWTYPE
    ) IS
        -- copies the input row to the tgt table
    BEGIN
        INSERT INTO
            tgt
        VALUES
            p_src;
    EXCEPTION
        WHEN OTHERS THEN
            log_err( SQLCODE, SQLERRM, p_src );
    END;

END;
/

但将数据从一个表复制到另一个表似乎是一种效率低下的可怕方式…

David,我认为你发布了错误的链接-我看不出这一链接的相关性?嗯,奇怪。即使是刚才我点击它的时候,它也对我有效。这肯定是一种科技。更正。。。谢谢托尼。大卫,我想你发错链接了-我看不出这一个有什么关联?嗯,奇怪。即使是刚才我点击它的时候,它也对我有效。这肯定是一种科技。更正。。。谢谢,托尼。你使用的是什么版本的Oracle?另外,您能否解释一下,当Oracle提供了几种更优雅的替代方案时,您为什么要使用这种可怕的机制来加载数据?如果您对源数据中的逻辑错误提出疑问,而不是DBMS可以检测到的错误,请查看MERGE语句,例如:您使用的Oracle版本是什么?另外,您能否解释一下,当Oracle提供了几种更优雅的替代方案时,您为什么要使用这种可怕的机制来加载数据?如果您对源数据中的逻辑错误而不是DBMS可以检测到的错误提出疑问,请查看MERGE语句,例如:here:@ammonQ:谢谢您的回答。你能给我一些有效的代码吗?我是pl/sql新手。有效的方法是“插入tgt select*from src where…”,检查where子句中可能出错的所有内容(不允许空值、值太长等)。是的,这可能意味着你必须在陈述中投入大量的精力。。。顺便说一句,如果我的答案有帮助,你可能想投票和/或接受它。要记录错误(实际上从未发生过,但如果你尝试插入tgt就会发生),你可以使用相同的方法:插入错误(…)从src中选择(…,-1,'名称不能为null'),其中name为null;等等@ammonQ:谢谢你的回复。你能给我一些有效的代码吗?我是pl/sql新手。有效的方法是“插入tgt select*from src where…”,检查where子句中可能出错的所有内容(不允许空值、值太长等)。是的,这可能意味着你必须在陈述中投入大量的精力。。。顺便说一句,如果我的答案有帮助,你可能想投票和/或接受它。要记录错误(实际上从未发生过,但如果你尝试插入tgt就会发生),你可以使用相同的方法:插入错误(…)从src中选择(…,-1,'名称不能为null'),其中name为null;等等。@kusosch:谢谢你的回复。这个代码是否有效,然后由ammoQ推荐。@kusosch:谢谢你的回复。这个代码是否有效,然后由ammoQ推荐。
CREATE OR REPLACE PACKAGE BODY foo_dml IS

    PROCEDURE log_err (
        p_sqlcode IN NUMBER,
        p_sqlerrm IN VARCHAR2,
        p_src     IN foo%ROWTYPE
    ) IS
        -- inserts the input row to the err log
    BEGIN
        INSERT INTO err (
            errno,
            errmsg,
            ID,
            NAME,
            ...
        ) VALUES (
            p_sqlcode,
            p_sqlerrm,
            p_src.id,
            p_src.name,
            ...
        );
    END;

    PROCEDURE copy_to_tgt (
        p_src IN foo%ROWTYPE
    ) IS
        -- copies the input row to the tgt table
    BEGIN
        INSERT INTO
            tgt
        VALUES
            p_src;
    EXCEPTION
        WHEN OTHERS THEN
            log_err( SQLCODE, SQLERRM, p_src );
    END;

END;
/