在開發的過程中,我們經常會遇到要生成一些固定格式字符串,例如“BX201903150001”,結構為:BX+日期+N位序號,類似這種的字符串我們很難生成,在這里我們借助一個存儲過程來實現這個功能。
1.創建表
該表用來存放我們要生成的字符串的規則和特性。
1 CREATE TABLE [dbo].[SYS_TableNO] 2 ( 3 [ID] [int] NOT NULL IDENTITY(1, 1), 4 [TableCode] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL, 5 [TableName] [varchar] (40) COLLATE Chinese_PRC_CI_AS NULL, 6 [PrefixCode] [varchar] (6) COLLATE Chinese_PRC_CI_AS NULL, 7 [UseTableName] [varchar] (40) COLLATE Chinese_PRC_CI_AS NULL, 8 [SysID] [int] NULL, 9 [Interval] [int] NULL CONSTRAINT [DF__SYS_Table__Inter__19071E83] DEFAULT ((1)), 10 [GetIDType] [int] NULL, 11 [SysIDLen] [int] NULL, 12 [LastSysCode] [varchar] (40) COLLATE Chinese_PRC_CI_AS NULL, 13 [LastSysDate] [datetime] NULL, 14 [Property] [int] NULL 15 ) ON [PRIMARY] 16 GO 17 ALTER TABLE [dbo].[SYS_TableNO] ADD CONSTRAINT [PK_MTableNO] PRIMARY KEY CLUSTERED ([TableCode]) ON [PRIMARY] 18 GO 19 EXEC sp_addextendedproperty N'MS_Description', N'表單號碼設置: 20 1、當表MOrganization新增時,默認按組織機構插入n條記錄 21 2、取單規則如下: 22 (1)GetIDType=1.按照2位前綴+8位日期+N位序號,日結時N位序號重置為0 23 (2)GetIDType=2.按照SYSID連續增長,不重置為0 24 (3)GetIDType=3.按照2位前綴+按照SYSID連續增長,不重置為0 25 (4)SysIDLength:當GETIDTYPE=1時,限制第三段的ID長度(N位序號);當GetIDType=2時,限制整段的SYSID長度 26 3、該表和存儲過程GetNO同時使用,可以實現兩種類型的單號:連續增長型的ID和符合規則的字符串Code,傳遞參數類型見存儲過程', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', NULL, NULL 27 GO 28 EXEC sp_addextendedproperty N'MS_Description', N'表單編碼:通常用相關表的主鍵字段來標識,但也有可能不是,大小寫混合', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'TableCode' 29 GO 30 EXEC sp_addextendedproperty N'MS_Description', N'表單名稱,例如:商品表、供應商采購訂單等', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'TableName' 31 GO 32 EXEC sp_addextendedproperty N'MS_Description', N'單據前綴,例如:訂單的號碼前綴為PO', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'PrefixCode' 33 GO 34 EXEC sp_addextendedproperty N'MS_Description', N'對應系統表名', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'UseTableName' 35 GO 36 EXEC sp_addextendedproperty N'MS_Description', N'系統有效ID', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'SysID' 37 GO 38 EXEC sp_addextendedproperty N'MS_Description', N'ID間隔,默認為1,如果是總部、門店同時做單,可以總部為1,門店為2,確保單號不會重復', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'Interval' 39 GO 40 EXEC sp_addextendedproperty N'MS_Description', N'獲取單號類型:1=按照n位前綴+8位日期+N位序號,日結時N位序號重置為0;2=按照SYSID連續增長,日結不重置為0', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'GetIDType' 41 GO 42 EXEC sp_addextendedproperty N'MS_Description', N'單號長度:如果是GetIDType=2,限制輸出Code的整體長度,ID連續增長;GetIDType=1,限制輸出Code后段的長度', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'SysIDLen' 43 GO 44 EXEC sp_addextendedproperty N'MS_Description', N'最后一次單據編碼', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'LastSysCode' 45 GO 46 EXEC sp_addextendedproperty N'MS_Description', N'最后一次單號日期,含時分秒', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'LastSysDate' 47 GO 48 EXEC sp_addextendedproperty N'MS_Description', N'表單屬性(Bit):0=用戶可以定制;1=用戶不可定制;2=不同組織具有不同的單號', 'SCHEMA', N'dbo', 'TABLE', N'SYS_TableNO', 'COLUMN', N'Property' 49 GO
2、插入數據
我們先創建一天數據,來設置我們要生成的字符串規范。例如‘BX201903150001’,前綴BX,中間是日期,最后是4位自增數字字符串,自增幅度為1,相應的字段說明可以參考上面注釋。
1 INSERT [dbo].[SYS_TableNO] 2 ( [TableCode] , 3 [TableName] , 4 [PrefixCode] , 5 [UseTableName] , 6 [SysID] , 7 [Interval] , 8 [GetIDType] , 9 [SysIDLen] , 10 [LastSysCode] , 11 [LastSysDate] , 12 [Property] 13 ) 14 VALUES ( N'BX-LivingPaymentNO' , 15 N'申請單號' , 16 N'BX' , 17 N'FY_LivingPayment' , 18 1 , 19 1 , 20 1 , 21 4 , 22 N'BX201903150001' , 23 '2019-03-15 12:00:00' , 24 1 25 );
3、存儲過程
接下來就是寫生成字符串的存儲過程,我們只需要將:表單編碼,傳入,就可以生成生成我們先要的對應的字符串,具體寫法如下
1 ALTER procedure [dbo].[PRC_SYS_GetNO] ( 2 @TableCode varchar(20), 3 @SysID int output, 4 @SysCode varchar(40) output 5 ) as 6 begin 7 declare @YEAR int,@MONTH int,@DAY int 8 declare @ISPACECODE int 9 DECLARE @LastSysDate CHAR(8),@GetIDType INT 10 select @YEAR=DATEPART(YY,GETDATE()),@MONTH=DATEPART(MM,GETDATE()),@DAY=DATEPART(DD,GETDATE()) 11 12 SELECT @LastSysDate=CONVERT(char(8), LastSysDate, 112),@GetIDType=GetIDType 13 FROM SYS_TableNO WHERE TableCode=@TableCode 14 15 --GetIDType=1.按照2位前綴+8位日期+N位序號,日結時N位序號重置為0 16 --GetIDType=2.按照SYSID連續增長,不重置為0 17 --SysIDLen:GetIDType=1時,限制第三段的ID長度;當GetIDType=2時,限制整段的SYSID長度 18 if exists(select 1 from SYS_TableNO where TableCode=@TableCode ) 19 begin 20 begin tran 21 --如果IDType=1且是當天首條記錄,將SysID更新為0 22 IF @GetIDType=1 AND @LastSysDate<>convert(char(8),@YEAR*10000+@MONTH*100+@DAY) 23 BEGIN 24 update SYS_TableNO set SysID=0+ISNULL(Interval,1) where TableCode=@TableCode 25 END 26 ELSE 27 begin 28 update SYS_TableNO set SysID=ISNULL(SysID,0)+ISNULL(Interval,1) where TableCode=@TableCode 29 end 30 select @SysCode=(case when GetIDType=1 then 31 PrefixCode+convert(char(8),@YEAR*10000+@MONTH*100+@DAY) 32 +right(convert(varchar,10000000000+SysID),SysIDLen) 33 when GetIDType=2 then right(convert(varchar,POWER(10,SysIDLen)+SysID),SysIDLen) 34 when GetIDType=3 then PrefixCode+right(convert(varchar,POWER(10,SysIDLen)+SysID),SysIDLen) 35 else 'NOT CONFIG.' END),@SysID=SysID 36 from SYS_TableNO 37 where TableCode=@TableCode 38 update SYS_TableNO set LastSysCode=@SysCode,LastSysDate=GETDATE() where TableCode=@TableCode 39 commit tran 40 end 41 end 42 GO
4、執行存儲過程
最后就是在我們的程序里進行執行存儲過程了,存儲過程返回來的就是我們需要的字符串,下面是我 的存儲過程執行代碼,這個要根據個人項目代碼具體實現。
1 model.PaymentNo = BLL_SYS_TableNO.SYS_TableNO_Bll.GetProcSYS_TableNoById("BX-LivingPaymentNO").SysCode;