怎样自定义字符串型自增加字段?

saucerman 2000-02-18 11:36:00
实际需求:

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中实现该多好呵!
不怕露丑,我这菜鸟现请教高手——
排除前端解决方案,不必拘泥于我的笨想法,请给出最佳方案!
回答请给出例子——我这人特笨!!!

...全文
420 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
929 2000-02-21
  • 打赏
  • 举报
回复
我想了一个办法,和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 tran
none 2000-02-19
  • 打赏
  • 举报
回复
我想了一个办法供你参考。

首先将表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上调试通过。
DOU 2000-02-18
  • 打赏
  • 举报
回复
你的方法很好啊,转换成stored procedure 试试
july 2000-02-18
  • 打赏
  • 举报
回复
bye,bye

34,694

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧