求触发器自动按日期生成序号

时间:2021-05-20 20:35:25
求触发器自动按日期生成序号

表名 sorder

列名 billid,billdate
     10001,2016-11-03
     10003,2016-11-03
     10005,2016-11-04

求:
1、按每日自动生成流水号 (每日生成流水号)
生成的单号如下:
SO20161103001
SO20161103002
SO20161104001

2、按每月自动生成流水号 (每月生成流水号)
SO201611001
SO201611002
SO201611003

5 个解决方案

#2


引用 1 楼 roy_88 的回复:
 如何实现自编号
http://blog.csdn.net/roy_88/article/details/1424370


谢谢!初学还是不知道如何按日和按月  自动生成单号。

#3


IF OBJECT_ID('T') IS NOT NULL
    DROP TABLE T;
GO
CREATE TABLE T
    (
      billid VARCHAR(20) PRIMARY KEY ,
      DayOfMonth VARCHAR(50) ,
      MonthOfYear VARCHAR(20) ,
      billdate DATETIME DEFAULT GETDATE()
    );

GO
--用触发器完成
CREATE TRIGGER tr_T_insert ON T
    INSTEAD OF INSERT
AS
    SET NOCOUNT ON;
    BEGIN
        DECLARE @DOM INT ,
            @MOY INT ,
            @Dt DATE= GETDATE();

        SELECT  @DOM = ISNULL(MAX(RIGHT(DayOfMonth, 3)), 0) + 1000000
        FROM    T WITH ( NOLOCK )
        WHERE   billdate >= @Dt;

        SELECT  @MOY = ISNULL(MAX(RIGHT(MonthOfYear, 3)), 0) + 1000000
        FROM    T WITH ( NOLOCK )
        WHERE   billdate >= CONVERT(VARCHAR(8), GETDATE(), 120) + '01';

        INSERT  INTO T
                ( billid ,
                  DayOfMonth ,
                  MonthOfYear
                )
                SELECT  billid ,
                        'SO' + CONVERT(VARCHAR(8), @Dt, 112) + RIGHT(@DOM
                                                              + ROW_NUMBER() OVER ( ORDER BY @Dt ),
                                                              3) ,
                        'SO' + CONVERT(VARCHAR(6), @Dt, 112) + RIGHT(@MOY
                                                              + ROW_NUMBER() OVER ( ORDER BY @Dt ),
                                                              3)
                FROM    inserted;


    END;



go
--测试
insert T(billid) 
select '1001'union all--这里1为任何值都不影响id插入的值
select '1002'

select * from T
/*
billid DayOfMonth MonthOfYear billdate
1001 SO20161103001 SO201611001 2016-11-03 19:55:25.740
1002 SO20161103002 SO201611002 2016-11-03 19:55:25.740
*/

insert T(billid) 
select '1003'union all--这里1为任何值都不影响id插入的值
select '1004'

select * from T
/*
billid DayOfMonth MonthOfYear billdate
1001 SO20161103001 SO201611001 2016-11-03 19:55:25.740
1002 SO20161103002 SO201611002 2016-11-03 19:55:25.740
1003 SO20161103003 SO201611003 2016-11-03 19:55:45.440
1004 SO20161103004 SO201611004 2016-11-03 19:55:45.440
*/

#4


+ 1000000  如果这里改为000  ,好像不行。因为我每日自动流水号是3位数字测试。

#5


本帖最后由 roy_88 于 2016-11-05 17:46:55 编辑
引用 4 楼 sankyqiu 的回复:
+ 1000000  如果这里改为000  ,好像不行。因为我每日自动流水号是3位数字测试。

看明白再改,不能乱改

你改了与数字加减时填充不了0

原理如下
e.g.

select right(1+1000,3),right(1+'000',3)

#1


#2


引用 1 楼 roy_88 的回复:
 如何实现自编号
http://blog.csdn.net/roy_88/article/details/1424370


谢谢!初学还是不知道如何按日和按月  自动生成单号。

#3


IF OBJECT_ID('T') IS NOT NULL
    DROP TABLE T;
GO
CREATE TABLE T
    (
      billid VARCHAR(20) PRIMARY KEY ,
      DayOfMonth VARCHAR(50) ,
      MonthOfYear VARCHAR(20) ,
      billdate DATETIME DEFAULT GETDATE()
    );

GO
--用触发器完成
CREATE TRIGGER tr_T_insert ON T
    INSTEAD OF INSERT
AS
    SET NOCOUNT ON;
    BEGIN
        DECLARE @DOM INT ,
            @MOY INT ,
            @Dt DATE= GETDATE();

        SELECT  @DOM = ISNULL(MAX(RIGHT(DayOfMonth, 3)), 0) + 1000000
        FROM    T WITH ( NOLOCK )
        WHERE   billdate >= @Dt;

        SELECT  @MOY = ISNULL(MAX(RIGHT(MonthOfYear, 3)), 0) + 1000000
        FROM    T WITH ( NOLOCK )
        WHERE   billdate >= CONVERT(VARCHAR(8), GETDATE(), 120) + '01';

        INSERT  INTO T
                ( billid ,
                  DayOfMonth ,
                  MonthOfYear
                )
                SELECT  billid ,
                        'SO' + CONVERT(VARCHAR(8), @Dt, 112) + RIGHT(@DOM
                                                              + ROW_NUMBER() OVER ( ORDER BY @Dt ),
                                                              3) ,
                        'SO' + CONVERT(VARCHAR(6), @Dt, 112) + RIGHT(@MOY
                                                              + ROW_NUMBER() OVER ( ORDER BY @Dt ),
                                                              3)
                FROM    inserted;


    END;



go
--测试
insert T(billid) 
select '1001'union all--这里1为任何值都不影响id插入的值
select '1002'

select * from T
/*
billid DayOfMonth MonthOfYear billdate
1001 SO20161103001 SO201611001 2016-11-03 19:55:25.740
1002 SO20161103002 SO201611002 2016-11-03 19:55:25.740
*/

insert T(billid) 
select '1003'union all--这里1为任何值都不影响id插入的值
select '1004'

select * from T
/*
billid DayOfMonth MonthOfYear billdate
1001 SO20161103001 SO201611001 2016-11-03 19:55:25.740
1002 SO20161103002 SO201611002 2016-11-03 19:55:25.740
1003 SO20161103003 SO201611003 2016-11-03 19:55:45.440
1004 SO20161103004 SO201611004 2016-11-03 19:55:45.440
*/

#4


+ 1000000  如果这里改为000  ,好像不行。因为我每日自动流水号是3位数字测试。

#5


本帖最后由 roy_88 于 2016-11-05 17:46:55 编辑
引用 4 楼 sankyqiu 的回复:
+ 1000000  如果这里改为000  ,好像不行。因为我每日自动流水号是3位数字测试。

看明白再改,不能乱改

你改了与数字加减时填充不了0

原理如下
e.g.

select right(1+1000,3),right(1+'000',3)