EXCEPTION后继续MERGE

时间:2014-10-23 08:55:07

标签: sql oracle exception plsql merge

是否可以在MERGE之后继续EXCEPTION

MERGE INTO copy_emp c
     USING employees e
     ON (c.employee_id = e.employee_id)
   WHEN MATCHED THEN
     UPDATE SET
       c.first_name     = e.first_name,
       c.last_name      = e.last_name,
       c.email          = e.email,
       c.phone_number   = e.phone_number,
       c.hire_date      = e.hire_date,
       c.job_id         = e.job_id,
       c.salary         = e.salary,
       c.commission_pct = e.commission_pct,
       c.manager_id     = e.manager_id,
       c.department_id  = e.department_id
   WHEN NOT MATCHED THEN
     INSERT VALUES(e.employee_id, e.first_name, e.last_name,
          e.email, e.phone_number, e.hire_date, e.job_id,
          e.salary, e.commission_pct, e.manager_id,
          e.department_id);

EXCEPTION
    WHEN OTHERS THEN
        -- ?????

除了检索抛出异常的行的ID并重新启动MERGE忽略此ID我不知道该怎么做。

我正在使用Oracle数据库10。

2 个答案:

答案 0 :(得分:3)

您可以使用error_logging_clause执行此操作。 (该链接用于插入,因为在MERGE的文档中,它表示它与插入具有相同的行为。

对于你的情况:

-- You create your Log Table
EXECUTE DBMS_ERRLOG.CREATE_ERROR_LOG('copy_emp', 'TAB_ERR_COPY_EMP');


    MERGE INTO copy_emp c
     USING employees e
     ON (c.employee_id = e.employee_id)
   WHEN MATCHED THEN
     UPDATE SET
       c.first_name     = e.first_name,
       c.last_name      = e.last_name,
       c.email          = e.email,
       c.phone_number   = e.phone_number,
       c.hire_date      = e.hire_date,
       c.job_id         = e.job_id,
       c.salary         = e.salary,
       c.commission_pct = e.commission_pct,
       c.manager_id     = e.manager_id,
       c.department_id  = e.department_id
   WHEN NOT MATCHED THEN
     INSERT VALUES(e.employee_id, e.first_name, e.last_name,
          e.email, e.phone_number, e.hire_date, e.job_id,
          e.salary, e.commission_pct, e.manager_id,
          e.department_id)
    LOG ERRORS INTO TAB_ERR_COPY_EMP('TAG_STATEMENT') REJECT LIMIT 100;

请注意,error_logging_clause有一些限制。来自文档:

  1. 以下条件导致语句失败并回滚 不调用错误记录功能:

    • 违反延期约束。

    • 任何引发唯一的直接路径INSERT或MERGE操作 约束或索引违规。

    • 任何引发唯一约束的更新操作UPDATE或MERGE 或索引违规)。

  2. 您无法在错误记录表中跟踪LONG,LOB或的错误 对象类型列。但是,表是目标的 DML操作可以包含这些类型的列。

    • 如果您创建或修改相应的错误记录表,那么 它包含一个不受支持的类型的列,如果它的名称 column对应于目标DML表中不受支持的列, 然后DML语句在解析时失败。

    • 如果错误记录表不包含任何不受支持的列 类型,然后记录所有DML错误,直到拒绝限制为止 达到了错误。对于发生错误的行,列值为 将记录错误日志记录表中的相应列 与控制信息。

答案 1 :(得分:1)

有几种方法可以避免终止。我一直主要使用FORALL SAVE EXCEPTIONS子句。

在Oracle数据库10g及更高版本中,PL / SQL为“继续超过异常”提供了三个选项,这实际上意味着避免终止当前块的执行。请阅读Steven Feuerstein撰写的这篇优秀文章,http://www.oracle.com/technetwork/issue-archive/2009/09-mar/o29plsql-085126.html