一直在使用FireBird,感觉不错,只可惜文档少了点(至少中文是这样),所以一直以来几乎都是自己慢慢地摸索。本来FireBird与InterBase师出同门,按理说用起来应该差不多的,于是就想买一本InterBase的书籍来进一步了解FireBird。后来听人说两者的区别还是很大的,就没买。

有点跑题了,进入正题。

数据库的自增字段几乎是逢表必用,在FireBird中使一个字段自增就要用触发器,一直觉得有点不爽,所以就决定撇开它,自己手动保证ID字段自增且不重复

刚开始,问题还好解决,新增时在存储过程中加一句
SELECT COALESCE(MAX(ID),0) + 1 INTO :MAX_ID
就解决了。可后来又遇到问题了:数据库中有大量的字典表,表结构很简单,就一个主键ID和一个字符型字段。如果为每一个字典表都写一个存储过程,有点划不来;如果为所有字典表写一个通用的存储过程,表名跟字段名的传递又有点麻烦。
SET TERM ^ ;

CREATE PROCEDURE SP_UD_DIC
        (ID integer,
        NAME VARCHAR(32),
        FIELD_NAME varchar(32),
        TABLE_NAME VARCHAR(32))
RETURNS

AS
DECLARE VARIABLE MAX_ID INTEGER;
DECLARE VARIABLE MCOUNT INTEGER;
BEGIN
        MCOUNT = 0;
        EXECUTE STATEMENT 'SELECT COUNT(ID) FROM ' + :TABLE_NAME INTO :MCOUNT;
        IF (MCOUNT > 0) then
        begin
                /*UPDATE*/
             EXECUTE STATEMENT 'UPDATE ' + :TABLE_NAME + ' SET ' + :FIELD_NAME + ' = ' + :NAME + 'WHERE ID = ' + :ID;
        END
        ELSE
        BEGIN
                /*INSERT*/
                /*....*/
        END
END^

SET TERM ; ^

最主要的原因是:如果改成上面的样子,程序的代码也有很大的改动。于是,就用了最简单的方法:在插入语句中实时筛选当前最大的ID并加1。
INSERT INTO TABLE(ID,NAME) VALUES((SELECT COALESCE(MAX(ID),0) + 1 FROM TABLE),'NAME');
这里要注意的是,FireBird中的嵌套语句必须用括号括起来,否则会报错。
COALESCE(MAX(ID),0)
上面这一句是安全代码,是为了防止空值扩散。