Com*_*sNo 5 firebird auto-increment firebird1.5
我目前正在修改Firebird v.1.5数据库.
数据库结构将被修改为使用interbase组件从delphi应用程序运行查询,我面临的问题是我需要运行大量查询,其中一些包括创建生成器和更新生成器值,问题在于我需要在尽可能少的查询中实现这一点,但似乎(至少对我而言)这不可能实现,我正在尝试做的是以下内容:
/* this command creates a generator to be used for table TABLENAME */
CREATE GENERATOR GEN_TABLENAME;
Run Code Online (Sandbox Code Playgroud)
所以我创建了一个生成器,现在我需要在表TABLENAME的当前最大id处设置它的值,如下所示:
/* one would expect that the following command would work, well it doesn't */
SET GENERATOR GEN_TABLENAME TO (SELECT MAX(ID) FROM TABLENAME);
Run Code Online (Sandbox Code Playgroud)
现在,有没有解决方法,或者我被迫:
并重复每个表的过程?
我也期待着
SELECT
SELECT MAX(ID) AS ID_TABLENAME_1 FROM TABLENAME_1,
...
SELECT MAX(ID) AS ID_TABLENAME_N FROM TABLENAME_N
Run Code Online (Sandbox Code Playgroud)
将是一个解决方法,从一个命令中的每个表中获取最大ID,但它没有.
声明
SET GENERATOR GEN_TABLENAME TO (SELECT MAX(ID) FROM TABLENAME);
Run Code Online (Sandbox Code Playgroud)
混合DDL(SET GENERATOR)和DML(SELECT),AFAIK通常不支持,Firebird肯定不支持它.
如果你可以升级到Firebird的最新版本,那么你可以使用EXECUTE BLOCK和/或EXECUTE STATEMENT来"在一个语句"和服务器端完成所有操作,但是使用Firebird 1.5你必须解决很长的问题(一个声明到得到当前的最大值,然后另一个更新发电机).
您可以创建一个存储过程并从 Delphi 调用它:
create procedure update_generators
as
declare variable max_id integer;
declare variable table_name char(31);
declare variable generator_name char(31);
begin
/* assuming generator naming convention GEN_XXX -> table name XXX */
for select
trim(g.rdb$generator_name),
substring(trim(g.rdb$generator_name) from 5)
from rdb$generators g
where (coalesce(g.rdb$system_flag, 0) = 0)
into
:generator_name,
:table_name
do
begin
/* assuming that the field name is always ID */
execute statement 'select max(id) from ' || :table_name into :max_id;
execute statement 'set generator ' || :generator_name || ' to ' || :max_id;
end
end^
Run Code Online (Sandbox Code Playgroud)
看起来Firebird 1.5 已经支持execute statement了。在 Firebird 2.0 及更高版本中,您还可以将代码包装在 a 中并避免创建存储过程。execute block
使用以下技巧,您可以在 Firebird 中使用一条 SQL 语句将生成器值设置为表的最大 ID 值:
SELECT GEN_ID( GEN_TABLENAME,
(SELECT MAX(ID) FROM TABLENAME) - GEN_ID(GEN_TABLENAME, 0)) FROM RDB$DATABASE;
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为GEN_ID( <GeneratorName>, <increment>)获取生成器值并将其增加<increment>. 这应该适用于 Firebird 1.5 以及更新的版本。
| 归档时间: |
|
| 查看次数: |
7363 次 |
| 最近记录: |