为什么不递增(Microsoft SQL)

时间:2018-07-20 11:49:15

标签: sql-server sql-server-2008 tsql

这是我的功能:

CREATE FUNCTION Ref_no() 
RETURNS CHAR(20) 
AS 
BEGIN 
    DECLARE @reff_no CHAR(20)
    DECLARE @result CHAR(20)

   /* SET @reff_no = (SELECT MAX(refno) FROM jobOffer WHERE refno LIKE CONCAT( MONTH(getDate()), '-', SUBSTRING(YEAR(getDate()),3,2), '-%'))*/
   SET @reff_no = (SELECT MAX(refno) FROM jobOffer ) 
    IF @reff_no is null 
        SET @result = CONCAT(RIGHT('00'+ CONVERT(VARCHAR, MONTH(getDate())),2), '-', SUBSTRING(CONVERT(varchar,YEAR(getDate())),3,2), '-', '000001')
    ELSE
        BEGIN
            DECLARE @reff_month CHAR(20)
            SET @reff_month = LEFT(@reff_no,2);
            Declare @month CHAR(20)
            SET @month = RIGHT('00'+CONVERT(VARCHAR, MONTH(getDate())),2);

            DECLARE @reff_year CHAR(20)
            SET @reff_year = CONVERT(VARCHAR,SUBSTRING(@reff_no,4,2));
            Declare @year CHAR(20)
            SET @year =  SUBSTRING(CONVERT(varchar,YEAR(getDate())),3,2);

                If ((@reff_year = @year)AND(@reff_month = @month))
                BEGIN
                    DECLARE @no INT
                    SET @no = CONVERT(int,RIGHT(@reff_no,6)) + 1 
                    DECLARE @s CHAR(20)
                    SET @s = RIGHT('000000' + CONVERT(VARCHAR(10),@no),6)
                    SET @result = CONCAT(RIGHT('00'+ CONVERT(VARCHAR, MONTH(getDate())),2), '-', SUBSTRING(CONVERT(varchar,YEAR(getDate())),3,2), '-',@s)
                END

                ELSE 
                    SET @result = CONCAT(RIGHT('00'+ CONVERT(VARCHAR, MONTH(getDate())),2), '-', SUBSTRING(CONVERT(VARCHAR,YEAR(getDate())),3,2), '-', '000001')

        END

RETURN @result

END
GO

这是我的桌子:

CREATE TABLE jobOffer (
    id int Primary Key Identity(1,1),
    refno varchar(20),
    code int,
    Full_Name nvarchar(50),
    Passport_no nvarchar(20),
);


INSERT INTO jobOffer (refno,code,Full_Name,Passport_no)VALUES (dbo.Ref_no(),12345, 'sdf', '123ec123' );
INSERT INTO jobOffer (refno,code,Full_Name,Passport_no)VALUES (dbo.Ref_no(),12345, '', '123ec123' );
INSERT INTO jobOffer (refno,code,Full_Name,Passport_no)VALUES (dbo.Ref_no(),12345, '', '123ec123' );
INSERT INTO jobOffer (refno,code,Full_Name,Passport_no)VALUES (dbo.Ref_no(),12345, '', '123ec123' );
INSERT INTO jobOffer (refno,code,Full_Name,Passport_no)VALUES (dbo.Ref_no(),12345, '', '123ec123' );
INSERT INTO jobOffer (refno,code,Full_Name,Passport_no)VALUES (dbo.Ref_no(),12345, '', '123ec123' );
select * from jobOffer

但是表y中的ref_no列未递增。

2 个答案:

答案 0 :(得分:1)

如果您不能保证从表中删除所有内容,那么我可以通过存储 date 来实现此目的,然后结合使用日期和id列来生成参考编号:

CREATE TABLE dbo._jobOffer (
    id int Primary Key Identity(1,1),
    _entryDate date not null default (CURRENT_TIMESTAMP),
    code int, /* TODO - Nullability? */
    Full_Name nvarchar(50),
    Passport_no nvarchar(20),
);
GO
CREATE VIEW dbo.jobOffer
with schemabinding
as
    select
        id,
        RIGHT('00' + CONVERT(varchar(2),DATEPART(month,_entryDate)),2) + '-' +
        RIGHT('00' + CONVERT(varchar(2),DATEPART(year,_entryDate)%100),2) + '-' +
        RIGHT('000000' + CONVERT(varchar(6),ROW_NUMBER() OVER (
            PARTITION BY DATEPART(month,_entryDate),
                         DATEPART(year,_entryDate)
            ORDER BY id)),6) as refno,
        code,
        Full_Name,
        Passport_no
    from
        dbo._jobOffer
go
INSERT INTO jobOffer (code,Full_Name,Passport_no)VALUES (12345, 'sdf', '123ec123' );
INSERT INTO jobOffer (code,Full_Name,Passport_no)VALUES (12345, '', '123ec123' );
INSERT INTO jobOffer (code,Full_Name,Passport_no)VALUES (12345, '', '123ec123' );
INSERT INTO jobOffer (code,Full_Name,Passport_no)VALUES (12345, '', '123ec123' );
INSERT INTO jobOffer (code,Full_Name,Passport_no)VALUES (12345, '', '123ec123' );
INSERT INTO jobOffer (code,Full_Name,Passport_no)VALUES (12345, '', '123ec123' );
select * from jobOffer

请注意,如果有多个人同时插入表中,则上述内容是安全。它也不会受到您的某些逻辑问题的困扰(例如,一旦您有12月的任何条目,那么您将再也找不到其他月份以来最新发布的参考号了,所有12位数字之间的事实)数字,与其他任何数字相比,以12....开头的数字始终是max()。这个问题普遍存在于其他月份)

结果:

id          refno        code        Full_Name                                          Passport_no
----------- ------------ ----------- -------------------------------------------------- --------------------
1           07-18-000001 12345       sdf                                                123ec123
2           07-18-000002 12345                                                          123ec123
3           07-18-000003 12345                                                          123ec123
4           07-18-000004 12345                                                          123ec123
5           07-18-000005 12345                                                          123ec123
6           07-18-000006 12345                                                          123ec123

我想您想要的是什么。如果没有,也许用您的预期结果 是什么来更新您的问题。

答案 1 :(得分:0)

您面临的根本问题是CHAR数据类型被填充为完整大小。

您的行:

SET @no = CONVERT(int,RIGHT(@reff_no,6)) + 1

不考虑这一点,因此右边的六个字符为空格。加1,结果始终为1。

您需要将其修改为:

SET @no = CONVERT(int,RIGHT(RTRIM(@reff_no),6)) + 1 

也就是说,如果可以,请避免使用CHAR,并使用VARCHAR。如本示例所示,CHAR难以使用且效率低下。将您所有的CHAR转换为VARCHAR也可以解决此问题。

最后的建议是,如果您要使用函数始终设置列的值,请使其成为表定义中的默认值,并且永远不必担心“记住”插入该表时再次调用哪个函数