首页 > 解决方案 > 如果我的表没有记录,如何获得下一个生成器值?

问题描述

我使用 Firebird 作为我的数据库,我想知道当没有数据时如何选择表的下一个生成器值?目前我正在使用这个脚本:

SELECT GEN_ID(" + sGEN_NAME + ", 1) FROM sGEN_TABLE

如果我的桌子上有记录,这很好用,否则它将不起作用!我正在考虑制作一个“助手 INSERT”,然后进行选择以获取 GEN_VALUE,然后删除记录。但是看起来很乱,还有其他方法吗?

标签: sqlfirebird

解决方案


使用RDB$DATABASE单行系统表是最简单和惯用的方式。

但是,为了完整起见,还有另一种方法。

https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-execblock.html

EXECUTE BLOCK 
  RETURNS (next_val integer /* BigInt in Firebird 3 */ )
AS
BEGIN
  next_val = GEN_ID ( gen_name, +1 ); 
END

此外,更多类似 SQL 的方式将用GEN_ID ( xxx, +1 )标准替换灵活但特定于 IB/FB 的NEXT VALUE FOR xxx.

https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-commons-expressions.html#fblangref25-commons-conditional-nxtvlufor

此外,“选择表的下一个生成器值”的任务听起来很奇怪。为什么你会想要这样做?在现代 Firebird 中,这应该是一些非常特殊的小众案例,当您实际上需要为如此简单的任务浪费一个独立的select查询时。通常,您只需在插入时立即获取表单生成器,例如通过一个相同的命令

INSERT INTO Table1( ID, Column1, Column2 ...)
VALUES ( GEN_ID(gen_name, +1), ? /* Param 1 */, ? /* Param 2 */ ...)
RETURNING ID

或者,如果您将ID赋值放入BEFORE UPDATE OR INSERTSQL 触发器中,只需

INSERT INTO Table1( Column1, Column2 ...)
VALUES ( ? /* Param 1 */, ? /* Param 2 */ ...)
RETURNING ID

您发送到服务器的查询越少 - 它工作得越快(请参阅:网络延迟,往返)并且您必须犯错误的代码越少。


推荐阅读