条件插入作为 HSQLDB 1.8 中的单个数据库事务?

Posted

技术标签:

【中文标题】条件插入作为 HSQLDB 1.8 中的单个数据库事务?【英文标题】:Conditional insert as a single database transaction in HSQLDB 1.8? 【发布时间】:2010-03-03 20:43:18 【问题描述】:

我正在使用一个特定的数据库表,例如“Set”数据结构,也就是说,您可以尝试多次插入同一行,但它只会包含一个实例。主键是自然键。例如,我希望以下一系列操作能够正常工作,并且只为俄克拉荷马州产生一行:

insert into states_visited (state_name) values ('Oklahoma');
insert into states_visited (state_name) values ('Texas');     
insert into states_visited (state_name) values ('Oklahoma');

由于后续插入相同值的主键重复,我当然会遇到错误。有没有办法使插入有条件,这样就不会抛出这些错误? IE。仅当自然键不存在时才进行插入?

我知道我可以先做一个 where 子句和一个子查询来测试该行是否存在,但这似乎很昂贵。这是一个逻辑“条件插入”操作的 2 个物理操作。 SQL中有类似的东西吗?

仅供参考,我使用的是 HSQLDB 1.8

【问题讨论】:

为什么不用数据库处理它的方式在 state_name 上创建唯一索引... B/C 然后它会抛出一个错误,我不想发生这种情况 【参考方案1】:

编辑:刚刚注意到您的问题不包括此答案。在任何情况下,数据库引擎都必须执行 where 检查,以执行唯一约束。

insert ... select 语句允许使用 where 子句:

insert into states_visited (state_name) 
select 'Oklahoma'
where not exists
(
    select  * 
    from    states_visited
    where   state_name = 'Oklahoma'
)

大多数 SQL 数据库将以事务方式执行单个语句。

【讨论】:

【参考方案2】:

如果您真的不关心被吞下的骗子,那么您就不能继续尝试插入,然后捕获异常吗?

...请记住,此代码被多次调用,这可能比您上面描述的 check-then-insert 方法性能低。

最后,您始终可以执行第一个建议,但在内存中保留先前看到的值(在该会话中)的缓存,这将限制执行异常处理的性能下降。

【讨论】:

【参考方案3】:

在纯 SQL 中无法做到这一点。您需要一种用于该任务的程序语言。例如,在 PL-SQL 中,您可以使用匿名 PL-SQL 块。

【讨论】:

【参考方案4】:

我想我会想使用MERGE command。

但是,我必须使用HSQLDB 1.9 or later。

【讨论】:

以上是关于条件插入作为 HSQLDB 1.8 中的单个数据库事务?的主要内容,如果未能解决你的问题,请参考以下文章

HSQLDB 只是插入中的时间值

HSQLDB 1.8 不能在派生表中进行排序?

如何在 HSQLDB 1.8 中查找表的标识列

索引 HSQLDB?

使用脚本创建表和插入数据未找到 HSQLDB 表

将数据库连接到 HSQLDB 服务器