【问题标题】:How can I get the next generator value if my table has no records?如果我的表没有记录,如何获得下一个生成器值?
【发布时间】:2019-12-10 23:25:18
【问题描述】:

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

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

如果我的桌子上有记录,这很好用,否则它将不起作用! 我正在考虑制作一个“助手插入”,然后选择获取 GEN_VALUE,然后删除记录。但是看起来这么乱,有没有别的办法?

【问题讨论】:

  • Works fine if there's records on my table - 不,它没有!它仅在单行时才能正常工作,否则会跳过许多值。除非你曾经(但你没有告诉)使用过 Select First(1) GEN+ID....

标签: sql firebird


【解决方案1】:

使用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 风格的方法是将灵活但特定于 IB/FB 的 GEN_ID ( xxx, +1 ) 替换为标准 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 INSERT SQL 触发器中,只需

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

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

【讨论】:

    【解决方案2】:

    所以我找到了答案,只需要将表名替换为rdb$database

    【讨论】:

      猜你喜欢
      • 2020-01-11
      • 1970-01-01
      • 2011-05-08
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 2015-11-12
      • 1970-01-01
      相关资源
      最近更新 更多