<!--StartFragment -->在数据库开发过程中,常会遇到这样的问题,一些订单(或其它单据)编号是根据日期+流水编号来生成的,如:今天是2003-11-25,那么今天开出的单号依次为:
20031125-1
20031125-2
20031125-3
……
到明天2003-11-26时,所开出的第一份单就应为:20031126-1
第二份单为:20031126-2
第三份单为:20031126-3
……
当然,通过客户端可以实现,但这样工程比较大,而且要考虑的东东实在太多。
那么数据库本身能自动生成上列这样格式的数据吗?如果能,又是如何自动生成的呢?
下面我来谈谈如何一步一步的来实现。
首先我们来建立一个测试的数据表:
CREATE TABLE "H_FORMATID"
(
"HT_ID" VARCHAR(15),
"HT_DATE" DATE,
"HT_SUBJECT" VARCHAR(60)
);
第一个字段 HT_ID 就是用来存储上列格数据的订单号,
第二个字段 HT_DATE 是用来存储当前日期内容的。
第三个字段 HT_SUBJECT 是用来存储数据内容的,
大伙可根据情况修改上列表,因这只是一个测试表而已。
我们知道,上列格式订单号的 "-" 前面的部份实际就是建立订单的当天的日期,所以很好解决,"-" 后面的部份是建立订单当天从1开始的流水编号,在IB/FB中,生成这样的流水编号当然离不开 Generator 了,所以我们还得建立一个生成器 GENERATOR 。
CREATE GENERATOR GEN_H_FORMATID;
而要让数据库每添加一笔数据时,订单编号(HT_ID)要自动填充数据,这时通常有两种方法去实现:
1:存储过程;
2:触发器(实际上也是一种存储过程)。
下面我们用建立触发器来实现:
SET TERM ^ ;
CREATE TRIGGER "TRI_BI_H_FORMATID" FOR "H_FORMATID"
ACTIVE BEFORE INSERT POSITION 0
AS
DECLARE VARIABLE h_d DATE;
/*
Author : 唐辉
http://www.3asoft.com
*/
BEGIN
SELECT MAX(HT_DATE) FROM H_FORMATID INTO :h_d;
/*查找最大的日期值*/
IF(CURRENT_DATE>h_d) THEN /*将当前日期与最大日期值比较*/
BEGIN
EXECUTE STATEMENT 'SET GENERATOR GEN_H_FORMATID TO 0';
/*如果当前日期大于库中的日期最大值,
*则将Generator值归零
*/
END
NEW.HT_ID=CAST(EXTRACT(YEAR FROM CURRENT_DATE) AS VARCHAR(4))||
/*取年*/
CAST(EXTRACT(MONTH FROM CURRENT_DATE) AS VARCHAR(2))||
/*取月*/
CAST(EXTRACT(DAY FROM CURRENT_DATE) AS VARCHAR(2))||'-'||
/*取日*/
CAST(GEN_ID(GEN_H_FORMATID,1) AS VARCHAR(7));
/*取GENERATOR值*/
NEW.HT_DATE=CURRENT_DATE; /*自动赋HT_DATE为当前日期*/
END
^
COMMIT WORK ^
SET TERM ;^
然后您往数据表里添加几条数据,再将您的系统日期增加一天,再添加几条数据试试,最终达到您的要求了,成功了,庆祝庆祝!!
以上代码在 FireBird 1.5 中测试成功,未在 InterBase 中测试。
20031125-1
20031125-2
20031125-3
……
到明天2003-11-26时,所开出的第一份单就应为:20031126-1
第二份单为:20031126-2
第三份单为:20031126-3
……
当然,通过客户端可以实现,但这样工程比较大,而且要考虑的东东实在太多。
那么数据库本身能自动生成上列这样格式的数据吗?如果能,又是如何自动生成的呢?
下面我来谈谈如何一步一步的来实现。
首先我们来建立一个测试的数据表:
CREATE TABLE "H_FORMATID"
(
"HT_ID" VARCHAR(15),
"HT_DATE" DATE,
"HT_SUBJECT" VARCHAR(60)
);
第一个字段 HT_ID 就是用来存储上列格数据的订单号,
第二个字段 HT_DATE 是用来存储当前日期内容的。
第三个字段 HT_SUBJECT 是用来存储数据内容的,
大伙可根据情况修改上列表,因这只是一个测试表而已。
我们知道,上列格式订单号的 "-" 前面的部份实际就是建立订单的当天的日期,所以很好解决,"-" 后面的部份是建立订单当天从1开始的流水编号,在IB/FB中,生成这样的流水编号当然离不开 Generator 了,所以我们还得建立一个生成器 GENERATOR 。
CREATE GENERATOR GEN_H_FORMATID;
而要让数据库每添加一笔数据时,订单编号(HT_ID)要自动填充数据,这时通常有两种方法去实现:
1:存储过程;
2:触发器(实际上也是一种存储过程)。
下面我们用建立触发器来实现:
SET TERM ^ ;
CREATE TRIGGER "TRI_BI_H_FORMATID" FOR "H_FORMATID"
ACTIVE BEFORE INSERT POSITION 0
AS
DECLARE VARIABLE h_d DATE;
/*
Author : 唐辉
http://www.3asoft.com
*/
BEGIN
SELECT MAX(HT_DATE) FROM H_FORMATID INTO :h_d;
/*查找最大的日期值*/
IF(CURRENT_DATE>h_d) THEN /*将当前日期与最大日期值比较*/
BEGIN
EXECUTE STATEMENT 'SET GENERATOR GEN_H_FORMATID TO 0';
/*如果当前日期大于库中的日期最大值,
*则将Generator值归零
*/
END
NEW.HT_ID=CAST(EXTRACT(YEAR FROM CURRENT_DATE) AS VARCHAR(4))||
/*取年*/
CAST(EXTRACT(MONTH FROM CURRENT_DATE) AS VARCHAR(2))||
/*取月*/
CAST(EXTRACT(DAY FROM CURRENT_DATE) AS VARCHAR(2))||'-'||
/*取日*/
CAST(GEN_ID(GEN_H_FORMATID,1) AS VARCHAR(7));
/*取GENERATOR值*/
NEW.HT_DATE=CURRENT_DATE; /*自动赋HT_DATE为当前日期*/
END
^
COMMIT WORK ^
SET TERM ;^
然后您往数据表里添加几条数据,再将您的系统日期增加一天,再添加几条数据试试,最终达到您的要求了,成功了,庆祝庆祝!!
以上代码在 FireBird 1.5 中测试成功,未在 InterBase 中测试。