在 Firebird 中为准备好的语句批次同时生成多个 ID

问题描述 投票:0回答:2

我正在使用

SELECT GEN_ID(TABLE,1) FROM MON$DATABASE
中的
PreparedStatement
来生成将在多个表中使用的 ID。

我将使用

INSERT
批次执行大量
PreparedStatement
,并且我正在寻找一种方法来从 Firebird 一次获取大量新 ID。

执行触发器似乎是不可能的,因为我必须在其他时间在 Java 代码中使用此 ID

INSERT
在其他表上。另外,
getGeneratedKeys()
批次似乎尚未在(我的?)Firebird JDBCdriver 中实现。

java sql prepared-statement firebird jaybird
2个回答
4
投票

我是凭记忆回答的,但我记得我曾经不得不将一堆交易从 Quicken 文件加载到我的 Firebird 数据库中。我加载了一个包含交易的数组,并将一个名为 iCount 的变量设置为该数字。然后我从 RDB$DATABASE 中执行 SELECT GEN_ID(g_TABLE, iCount) 。这给了我下一个 ID,并根据我要插入的记录数增加了生成器。然后我启动了一个事务,单步遍历数组并逐个插入记录并关闭事务。我很惊讶这一切进展得如此之快。我想,当时我正在处理大约 28,000 笔交易,时间只有几秒钟。像这样的东西可能对你有用。


1
投票

正如 jrodenhi 所说,您可以使用

保留一系列值
SELECT GEN_ID(<generator>, <count>) FROM RDB$DATABASE

这将返回比之前生成的键高

<count>
的值,因此您可以使用
(value - count, value]
中的所有值(其中
(
表示排除,
]
表示包含)。假设生成器当前的值为 10,调用
GEN_ID(generator, 10)
将返回 20,然后您可以使用 11...20 作为 ids。

这确实假设您通常使用生成器为表生成 id,并且没有应用程序在不使用生成器的情况下构建自己的 id。

正如您所注意到的,Jaybird 2.2.x 中的批次尚未实现

getGeneratedKeys()
。 Jaybird 3.0.0 中将提供对此选项的支持,请参阅 JDBC-452

除非您还针对其他数据库,否则在使用 Firebird 3.0 或更早版本时使用批量更新(在 Jaybird 中)并没有真正的性能优势。 Firebird 3.0 及更早版本不支持批量更新,因此 Jaybird 的内部实现本质上与准备语句并自己重复执行相同。

要受益于 Firebird 4.0 及更高版本的批量更新,您需要使用 Jaybird 5 或更高版本(请参阅 Jaybird 5 发行说明中的Firebird 4.0 服务器端批量更新)。

披露:我是 Jaybird 开发者之一

© www.soinside.com 2019 - 2024. All rights reserved.