Posted on 2005-05-08 20:54
二十四画生 阅读(2474)
评论(11) 编辑 收藏
大多数的单据都需要有个单据号。有的单据号就是顺序编号如:000001,000002……。有的单据号是有一定意义的,如我遇见过的一个需求:单据号共12位,1位帐套号(区分使用单位的),1位单据标识号(表示该单是什么单,如:E表示订货单,X表示销售单),2位年号(05表示2005年),2位月号,2位日号,4位编号(按当天的顺序,最大9999,超过9999的就用9999表示)
JE0505070001就表示某某单位2005年5月7日的第一单订货单。用编程实现这个要求当然不算太难,不过要将单据号生成方法放到存储过程中去就要费点心思了。
下面就以插入订单为例,其中有一段代码是可提取到一个单独的存储存储过程中的,这样可增加通用性。
-插入客户订单
CREATE PROCEDURE InsertOrder
(
@CustomerId int,
@MX nvarchar(4000),
@Incom smallint
)
AS
SET NOCOUNT ON
--这一个部分还可单独提取到一个存储过程中通过传入“单据标识号”和“单据表名”为参数---------------------------------------
--找帐套字头号
DECLARE @IH char(1)
SELECT @IH = LEFT(IncID,1) FROM accounts WHERE ID = @Incom
--编号年月部分
DECLARE @YM char(6)
SET @YM = CONVERT(char(6),GETDATE(),12)
--单据字头
DECLARE @DJHH char(8)
SET @DJHH = @IH + 'E' + @YM
--找编号的基值(方法:用当天的编号到排序取最大的一个。如当前最大编号为0001那么它的基值为1,这样就能得出下个编号为0002)
DECLARE @MNO INT --当天最大的单据号(数值)
SET @MNO = 1
select TOP 1 @MNO = CONVERT(int,RIGHT(DJH,4))+1 from Orders where left(DJH,8) = @DJHH and incom = @Incom Orders by DJH desc
DECLARE @DJH char(12)
--扩充成4位十进制编号(最大可显示9999)
IF @MNO < 9999
IF @MNO < 999
IF @MNO < 99
IF @MNO < 9
SET @DJH = @DJHH + '000' + CONVERT(char(1),@MNO)
ELSE
SET @DJH = @DJHH + '00' + CONVERT(char(2),@MNO)
ELSE
SET @DJH = @DJHH + '0' + CONVERT(char(3),@MNO)
ELSE
SET @DJH = @DJHH + CONVERT(char(4),@MNO)
ELSE
SET @DJH = @DJHH + '9999'
----(可提取的部分结束)------------------------------------------------------------------------------------------------------
--插入订单
INSERT INTO Orders (DJH, CustomerId, MX, InCom) VALUES (@DJH, @CustomerId, @MX, @Incom)
RETURN
GO
--种子表 num_tb
create table num_tb(d datetime,id int)
insert num_tb select '2004-01-01',1
create table tb(id varchar(20),name varchar(10))
create clustered index idx_clu_tb on tb(id)
go
create trigger tri_tb on tb
INSTEAD OF INSERT
as
begin
set nocount on
declare @i int,@id varchar(20),@j int
select @i=count(*) from inserted
begin tran
if exists(select 1 from num_tb where convert(char(8),d,112)=convert(char(8),getdate(),112))
begin
select @j=id from num_tb with(TABLOCKX)
update num_tb with(TABLOCKX) set id=id+@i
end
else
begin
update num_tb with(TABLOCKX) set d=getdate(),id=@i
set @j=0
end
commit tran
select * into #t from inserted
update #t set id=convert(varchar(8),getdate(),112)+right('00000'+rtrim(@j),5),@j=@j+1
insert tb select * from #t
end
go
alter trigger tri_tb on tb
INSTEAD OF INSERT
as
begin
set nocount on
declare @i int,@id varchar(20),@j int
select @i=count(*) from inserted
begin tran
update num_tb with(TABLOCKX) set
id=(case when convert(char(8),d,112)=convert(char(8),getdate(),112)
then id+@i else @i end),
@j=(case when convert(char(8),d,112)=convert(char(8),getdate(),112) then id else 0 end),
d=getdate()
commit tran
select * into #t from inserted
update #t set id=convert(varchar(8),getdate(),112)+right('00000'+rtrim(@j),5),@j=@j+1
insert tb select * from #t
end
go
--创建表
go
--插入记录测试
declare @i int
set @i=0
while @i<=10000
begin
insert into tb(name) values('张三')
insert into tb(name) select '张四'
union all select '张五'
union all select '张六'
union all select '张七'
union all select '张八'
union all select '张九'
union all select '张十'
set @i=@i+1
end
go
--删除环境
drop table tb
二十四你好。发现这个存储过程的一点小问题。
IF @MNO < 9
应该是IF @MNO < 10
否则到9就会有问题。