怎样自定义字符串型自增加字段?
实际需求:
job(工作表),其主键job_id为VarChar(11)
需要自定义为按下述方式自增加:
比如,今天为2000.02.18
从头一条记录起,job_id分别自增加为:
20000218001
20000218002
20000218003
20000218004
.
.
.
如果日期到了第二天2000.02.19,又自动依次增量产生为:
20000219001
20000219002
20000219003
20000219004
.
.
.
曾经用过如下方法:
create table job
(job_id varchar(11) default '00000000000'
constraint PK_job primary key clustered,
jobdscrpt varchar(50))
create trigger trg_autojobid on job for insert
as
declare @last_jobid varchar(11)
declare cur_findlast scroll cursor
for select job_id from job
open cur_findlast
fetch last from cur_findlast
into @last_jobid
close cur_findlast
deallocate cur_findlast
if (convert(varchar(11),getdate(),112)=substring(@last_jobid,1,8))
begin
update job
set job_id=
convert(varchar(11),getdate(),112)+
substring('000',1,3-datalength(convert(varchar(11),
convert(int,substring(@last_jobid,9,3))+1)))+
convert(varchar(11),convert(int,substring(@last_jobid,9,3))+1)
where job_id='00000000000'
end
else
begin
update job
set job_id=convert(varchar(11),getdate(),112)+'001'
where job_id='00000000000'
end
这种方法在纯SQL Server的环境中绝对没问题,但拿到BCB或Delphi的BDE连接下出错。
并且本身也太繁锁。
当然可以通过前台编程实现和解决——我最后也是通过前端编程做出来的。
但总贼心不死——要是直截在后端SQL中实现该多好呵!
不怕露丑,我这菜鸟现请教高手——
排除前端解决方案,不必拘泥于我的笨想法,请给出最佳方案!
回答请给出例子——我这人特笨!!!
问题点数:25、回复次数:4Top
1 楼july(沉船侧畔)回复于 2000-02-18 12:26:00 得分 0
bye,byeTop
2 楼DOU()回复于 2000-02-18 12:58:00 得分 1
你的方法很好啊,转换成stored procedure 试试Top
3 楼none(纯钢匕首)回复于 2000-02-19 17:24:00 得分 12
我想了一个办法供你参考。
首先将表job的主键拆开为日期和序号两部分
CREATE TABLE job (
j_date char(8) NOT NULL DEFAULT (CONVERT(CHAR(8),getdate(),112)),
j_sn char(3) NOT NULL DEFAULT '000',
jobdscrpt varchar(50) NULL )
GO
ALTER TABLE job ADD CONSTRAINT [PK_job] PRIMARY KEY
NONCLUSTERED (j_date, j_sn)
其次建立一个表存放当前的日期和当天最大的流水号(这个表还可以存其它表的
某些列的最大值)
CREATE TABLE keys (type varchar (20) PRIMARY KEY ,value varchar (20)
NOT NULL )
然后向表keys中插入表示当前日期和最大序号的行
INSERT INTO keys (type, value) VALUES('j_date', '')
GO
INSERT INTO keys (type, value) VALUES('j_sn',0)
最后是建立触发器
CREATE TRIGGER trg_autojobid on job for insert as
declare @cur_date char(8), @max_value char(6)
select @cur_date = convert(char(8),getdate(),112)
if not exists (select value from keys where type = 'j_date' and
value = @cur_date)
begin
update keys set value = @cur_date where type = 'j_date'
update keys set value = '000' where type = 'j_sn'
end
select @max_value=right('000'+ltrim(str(convert(int,value)+1)),3)
from keys where type='j_sn'
update job set j_sn = @max_value where j_sn = '000'
update keys set value = @max_value where type = 'j_sn'
上述语句我在MS SQL7上调试通过。Top
4 楼929()回复于 2000-02-21 12:59:00 得分 12
我想了一个办法,和NONE差不多。而且在处理时只能处理一行INSERT的情况。想法是这样的:在插入时,判断行数是否为一行,若是的话,在序号表中取值来更新字符串值。
/****** Object: Trigger dbo.tr_charid_insert Script Date: 00-2-21 13:10:01 ******/
if exists (select * from sysobjects where id = object_id('dbo.tr_charid_insert') and sysstat & 0xf = 8)
drop trigger dbo.tr_charid_insert
GO
/****** Object: Table dbo.charid Script Date: 00-2-21 13:10:01 ******/
if exists (select * from sysobjects where id = object_id('dbo.charid') and sysstat & 0xf = 3)
drop table dbo.charid
GO
/****** Object: Table dbo.id Script Date: 00-2-21 13:10:01 ******/
if exists (select * from sysobjects where id = object_id('dbo.id') and sysstat & 0xf = 3)
drop table dbo.id
GO
/****** Object: Table dbo.charid Script Date: 00-2-21 13:10:01 ******/
CREATE TABLE dbo.charid (
charid char (11) NOT NULL ,
intnull int IDENTITY (1, 1) NOT NULL ,
CONSTRAINT PK_charid_1__10 PRIMARY KEY CLUSTERED
(
charid
)
)
GO
/****** Object: Table dbo.id Script Date: 00-2-21 13:10:02 ******/
CREATE TABLE dbo.id (
id int NOT NULL
)
GO
/****** Object: Trigger dbo.tr_charid_insert Script Date: 00-2-21 13:10:02 ******/
CREATE TRIGGER tr_charid_insert ON dbo.charid
FOR INSERT
AS
declare @id varchar(3),@row int
select @row=@@rowcount
if (@row>1)
begin
print "Can't insert more than one row"
rollback transaction
end
else
begin
update id set id=id+1
select @id=right('000'+ltrim(str(id+1)),3) from id
update charid set c.charid=convert(varchar(8),getdate(),112)+convert(varchar(3),@id) from charid c,inserted i where c.intnull=i.intnull
end
GO
其中ID表做为序号发生器,以保证序号连续,如果对连续要求不高,可用IDETITY类型代替。
我写了个SQL来验证这个触发器。
begin tran
insert charid(charid) values('1')
insert charid(charid) values('1')
select * from charid
rollback tranTop




