我正在使用特定的数据库表,如“Set”数据结构,即,您可以尝试多次插入同一行,但它只包含一个实例。主键是一个自然键。例如,我希望以下一系列操作正常工作,并且只为Oklahoma产生一行:
insert into states_visited (state_name) values ('Oklahoma');
insert into states_visited (state_name) values ('Texas');
insert into states_visited (state_name) values ('Oklahoma');
由于后续插入相同值的重复主键,我当然会收到错误。有没有办法使插入条件,以便不抛出这些错误?即如果自然键还不存在,那么只进行插入吗?
我知道我可以先使用where子句和子查询来测试行的存在,但看起来这样会很昂贵。这是一个逻辑“条件插入”操作的2个物理操作。 SQL中有这样的东西吗?
仅供参考我使用的是HSQLDB 1.8
答案 0 :(得分:2)
insert ... select
语句允许where子句:
insert into states_visited (state_name)
select 'Oklahoma'
where not exists
(
select *
from states_visited
where state_name = 'Oklahoma'
)
大多数SQL数据库将以事务方式执行单个语句。
答案 1 :(得分:0)
如果你真的不在乎被吞下的骗局,那么你不能继续尝试插入,只是抓住异常吗?
...请记住,这个代码被大量调用,这可能不如您在上面描述的check-then-insert方法高效。
最后,你总是可以做第一个建议但是在内存中保存一个先前看到的值(在那个会话中),这将限制执行异常处理的性能下降。
答案 2 :(得分:0)
在纯SQL中无法做到这一点。您需要一个过程语言来完成任务。例如,在PL-SQL中,您可以使用匿名PL-SQL块。
答案 3 :(得分:0)
我想我会想要使用MERGE command。
但要这样做,我将不得不使用HSQLDB 1.9 or later。