如何从 SQL *PLUS 中的批量插入中查找失败的插入语句

Posted

技术标签:

【中文标题】如何从 SQL *PLUS 中的批量插入中查找失败的插入语句【英文标题】:How to find failed insert statements from bulk inserts in SQL *PLUS 【发布时间】:2018-05-09 21:54:03 【问题描述】:

我一直试图通过 SQL *PLUS 在我的表中插入近 10K 行。但是,当我计算 SQL DEVELOPER 时,10K 行中缺少近 10 行。

如何查找哪些行插入失败?

我已经在 Excel 中准备了插入脚本,并从 Excel 中复制了 10K 行并粘贴到 SQL *PLUS 中。此过程在 5 分钟内完成,但缺少一些行。

请帮我找到那些缺失的行。

【问题讨论】:

插入失败时不会出错吗? 将 sqlplus' 输出到一个文件中并 grep 查找文件中的错误 【参考方案1】:

这个问题很模糊,我猜测你的脚本的确切形式,所以我的回答试图为你提供一些选择,但并不精确。

你可以试试这样的:

WHENEVER SQLERROR EXIT FAILURE COMMIT
INSERT INTO t1 VALUES ( 'a', 'b', 'c');
INSERT INTO t1 VALUES ( 'a1', 'b1', 'c1');
.
.

这将导致脚本在第一个错误处停止,但使用 COMMIT 可以让您看到您已经走了多远(假设插入顺序中有一些逻辑顺序)。

这是磨练错误的一种快速而肮脏的方法。

第二种方法是散布提示以显示正在插入的值以帮助调试:

WHENEVER SQLERROR EXIT FAILURE ROLLBACK
PROMPT INSERTING a, b, c
INSERT INTO t1 VALUES ( 'a', 'b', 'c');
PROMPT INSERTING a1, b1, c1
INSERT INTO t1 VALUES ( 'a1', 'b1', 'c1');
.
.

另一个想法,涉及更多一点。假设您使用 EXCEL 生成 INSERT 语句,您可以将它们生成为对 pr_insert 过程的调用,然后在过程中使用逻辑来捕获和标记错误:

CREATE OR REPLACE PROCEDURE pr_insert
   ( p1 IN t1.c1%TYPE,
     p2 IN t1.c2%TYPE,
     p3 IN t1.c3%TYPE ) AS
BEGIN
   INSERT INTO t1 VALUES ( p1, p2, p3 );
EXCEPTION
   WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR ( -20001, 'Error on : ' || p1 || ',' || p2 || 'p3 );
END ;
/

可以在 Excel 中生成以下 pr_insert 调用:

BEGIN
  pr_insert ( 'a', 'b', 'c' );
  pr_insert ( 'a1', 'b1', 'c1' );
  pr_insert ( 'a2', 'b2', 'c2' );
.
.
END;
/

【讨论】:

非常感谢@TenG,它非常有帮助并且是完美的答案。结尾部分有点混乱,如果可能的话,你能解释一下吗?是的,我正在准备在 Excel 中插入脚本。 重新成为“结束部分”,创建存储过程 pr_insert 以接受插入值作为参数,并在插入失败时抛出异常打印值。然后在您的 Excel 中,而不是生成“INSERT...”语句,而是生成“pr_insert(...”语句。【参考方案2】:
Here is one way to find missing rows , mostly table will have one primary key or make primary key using sequence ... try to load primary key alone in another table say lookup table  .... Then make query between actual loaded table and lookup table to find missing rows

create table temp
( id number,
sal number)

begin 
insert into temp values (1,100);
insert into temp values (2,200);
insert into temp values (3,300);
insert into temp values (5,400);
end;

select * from temp;

create table lookup
(id number);

begin 
insert into lookup values(1);
insert into lookup values(2);
insert into lookup values(3);
insert into lookup values(4);
insert into lookup values(5);
end;

select * from lookup;

select * from lookup where id not in ( select id from temp);

【讨论】:

以上是关于如何从 SQL *PLUS 中的批量插入中查找失败的插入语句的主要内容,如果未能解决你的问题,请参考以下文章

SQL 代理作业中的批量插入失败,未找到文件

在 Python 中使用 cx_Oracle 中的 executemany() 从批量插入数据加载中查找错误记录

批量从Dataframe插入到DB,忽略Pyspark中的失败行

从数据框批量插入到数据库,忽略 Pyspark 中的失败行

PL/SQL 编译失败时如何让 SQL*Plus 退出

MS SQL 批量更新\插入