Sql 在Oracle 11中使用合并查询记录日志时出错

Sql 在Oracle 11中使用合并查询记录日志时出错,sql,oracle11g,query-tuning,Sql,Oracle11g,Query Tuning,我正在使用Oracle 11,我的表中有数百万条记录。我使用MERGE语句将记录从源表更新到目标表 在更新这数百万条记录的任何时候,如何记录每条记录的错误 例如:我已成功更新了400条记录,但在更新第401条记录时,我遇到了一些错误,因此在这种情况下,我如何记录类似的内容 第401条记录及其失效原因 因此,从这些数百万条记录中,我可以确定查询失败的记录。您不能选择自己的错误,但可以使用error\u logging\u子句。请参阅Oracle文档,网址为 首先需要使用DBMS_ERRLOG创建一

我正在使用Oracle 11,我的表中有数百万条记录。我使用
MERGE
语句将记录从源表更新到目标表

在更新这数百万条记录的任何时候,如何记录每条记录的错误

例如:我已成功更新了400条记录,但在更新第401条记录时,我遇到了一些错误,因此在这种情况下,我如何记录类似的内容

第401条记录及其失效原因


因此,从这些数百万条记录中,我可以确定查询失败的记录。

您不能选择自己的错误,但可以使用error\u logging\u子句。请参阅Oracle文档,网址为

首先需要使用DBMS_ERRLOG创建一个错误日志表。在merge语句的末尾,您需要加上

LOG ERRORS INTO <<errorLogTableName>> 
将错误记录到

您不能选择自己的错误,但可以使用error\u logging\u子句。请参阅Oracle文档,网址为

首先需要使用DBMS_ERRLOG创建一个错误日志表。在merge语句的末尾,您需要加上

LOG ERRORS INTO <<errorLogTableName>> 
将错误记录到

您可以将错误记录在同一个表或您选择的表中。在下面提供的示例中,我创建了一个名为
tst\u merge
的表,并将7行数据填充到两列
column1
data\u to\u update
,以保持简单。为了保持这种简单性,我创建了一个第三列的表来存储任何Oracle错误,但该列可以位于任何表中,最好位于用于跟踪这些错误的表中

这个答案还假设您至少对PL/SQL有点熟悉。使用我的示例,如果没有PL/SQL,我想不出实现这一点的方法

设置表格和插入数据代码如下:

执行您请求的操作的代码如下所示。PL/SQL

请在下面的Gif中查看它的运行情况


您可以将错误记录在同一个表或您选择的表中。在下面提供的示例中,我创建了一个名为
tst\u merge
的表,并将7行数据填充到两列
column1
data\u to\u update
,以保持简单。为了保持这种简单性,我创建了一个第三列的表来存储任何Oracle错误,但该列可以位于任何表中,最好位于用于跟踪这些错误的表中

这个答案还假设您至少对PL/SQL有点熟悉。使用我的示例,如果没有PL/SQL,我想不出实现这一点的方法

设置表格和插入数据代码如下:

执行您请求的操作的代码如下所示。PL/SQL

请在下面的Gif中查看它的运行情况


嗨,RockingDev!如果有任何答案是有帮助的,请将其标记为有帮助的答案。如果您发现其中任何一个匹配为适当的答案,请将其设置为答案,以便Stackoverflow社区看到找到了答案。在你提出的所有社区已经回答的问题中,似乎没有一个答案标有后续。嗨,RockingDev!如果有任何答案是有帮助的,请将其标记为有帮助的答案。如果您发现其中任何一个匹配为适当的答案,请将其设置为答案,以便Stackoverflow社区看到找到了答案。在您提出的所有社区已回答的问题中,似乎没有一个答案标有后续内容。
DECLARE
  /* Store Error Code and Message so we can log these values into a table */ 
  sql_error_num   NUMBER          :=  0;
  sql_error_msg   VARCHAR2(100)   :=  '';

  CURSOR cur_MergeData IS
    SELECT column1, data_to_update
      /* The below line builds a character n times as the new string to update into the data_to_update field */
      /* Here this is simply going to force the error ORA-12899 'Value Too Large for Column'                 */
      , rpad('L', (to_number(SUBSTR(column1, 1, 1)) * 2), 'L') AS new_string
    FROM tst_merge
    ;

  TYPE t_MergeData IS TABLE OF cur_MergeData%ROWTYPE; /* Type declared based on Cursor     */
  c_MergeData  t_MergeData  :=  t_MergeData();        /* Collection declared based on Type */


BEGIN

  OPEN cur_MergeData;
    FETCH cur_MergeData BULK COLLECT INTO c_MergeData; /* Fill Collection with data from Cursor */
  CLOSE cur_MergeData;

  IF c_MergeData.COUNT > 0 THEN
    FOR r IN c_MergeData.FIRST .. c_MergeData.LAST
    LOOP

      BEGIN
          /* Output row data just for troubleshooting */
          dbms_output.put_line(c_MergeData(r).column1 ||' '|| c_MergeData(r).new_string );

          /* Merge Code */
          MERGE INTO tst_merge tm USING
          (
          SELECT column1, data_to_update
          FROM /* When Merging into the same table the MERGE INSERT ONLY works if a record is returned. */
               /* The dual table forces a record with columns values of NULL to be returned if NO MATCH is found. */
            (SELECT 1 AS fake FROM dual) d
            LEFT JOIN tst_merge t ON t.column1 = c_MergeData(r).column1
          ) m ON (m.column1 = tm.column1)

          WHEN MATCHED THEN       

          UPDATE SET data_to_update = c_MergeData(r).new_string
          WHERE column1 = c_MergeData(r).column1

          WHEN NOT MATCHED THEN

          INSERT (column1, data_to_update)
          VALUES (c_MergeData(r).column1, c_MergeData(r).new_string)
          ;

      EXCEPTION       
        WHEN OTHERS THEN 
          sql_error_num :=  SQLCODE;
          sql_error_msg :=  SQLERRM;

          DBMS_OUTPUT.put_line('Error '||TO_CHAR(sql_error_num)||': '||sql_error_msg);

          UPDATE tst_merge SET db_error = ('Error '||TO_CHAR(sql_error_num)||': '||sql_error_msg)
          WHERE column1 = c_MergeData(r).column1;

      END;          

    END LOOP;
  END IF;

END
;