尝试在DB2插入中避免使用-803

时间:2010-01-13 17:36:55

标签: db2

我正在尝试插入可能已存在或可能尚未存在的单行。我想避免先选择它和/或如果它确实存在则获得-803。我已经完成了一些研究,并尝试了忽略和merge语句,但是两者都不断出现语法错误。无论如何,我不是试图从另一个表中复制数据 - 因此,合并并不合适 DB2 SQL中是否有某种方式只发出一个防故障插入而不必编写代码?换句话说,是否有一些插入语法可以保证数据不存在时会被添加,或者即使它也会返回零状态?

4 个答案:

答案 0 :(得分:7)

MERGE 是合适的,因为您可以在USING子句中动态提供值(参见http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/r0010873.htm中的示例5)。

但MERGE是DB2 V8.2的一个特性!你可能在V8.1上,不是吗?

如果你实现这样的存在检查:

SELECT
if (found) UPDATE else INSERT

注意并发问题:两个并发线程可能都找不到列,然后两者都尝试插入,即使围绕上面的代码有一个事务。为确保不会发生这种情况,您需要使用WITH RR USE AND KEEP UPDATE LOCKS在上述SELECT语句中获取带有Repeatable Read 的更新锁。

答案 1 :(得分:2)

简而言之,答案是否定的。总之,这完全取决于您在桌面上设置的限制。如果您尝试对列上具有唯一约束的表执行插入,并且您尝试插入的数据已存在,那么您将在DB2(以及任何其他RDBMS)中收到错误。

在这种情况下,您最好的选择可能是编写一个存储过程,在创建记录之前检查该记录是否已存在。

答案 2 :(得分:2)

您可以执行update语句,如果返回0结果更新,则执行insert语句。

答案 3 :(得分:2)

您可以使用sysibm.sysdummy表(或Oracle中更好的命名对偶或更高版本的DB2)来执行此操作。对于要插入不存在的行但如果存在则返回0的情况,这将非常有效。 AFAIK,您无法使用此方法更新行,您需要使用合并。

要执行此操作,您需要在桌面上使用主键或唯一键。您插入表中,在表中不存在与主索引或唯一索引匹配的行的过程中从双精度值中选择所有值。

insert into table (column1, column2, column3, column4, column5)
select 'A', 'B', 'C', 'D', 'E' from dual where not exists (select * from table where column1 = 'A');

我发现这对于我有多个进程插入表的情况非常有用,我无法保证这些插入的顺序。您可以通过返回值检测插入是否成功,如果成功则为1,如果不成功则为0