'Id' 格式为:YYYYNNNNNN,NNNNNN 部分每年重新开始

Dar*_*mas 11 sql-server t-sql

我有一个业务需求,即发票表中的每条记录都有一个看起来像 YYYYNNNNNN 的 ID。

NNNNNN 部分需要在每年年初重新启动。所以 2016 年输入的第一行看起来像 2016000001,第二行看起来像 2016000002 等等。假设 2016 年的最后一条记录是 2016123456,下一行(2017 年)应该看起来像 2017000001

我不需要这个 id 作为主键,我也存储创建日期。这个想法是这个'显示ID'是独一无二的(所以我可以通过它查询)并且可以按年份进行分组。

不太可能删除任何记录;但是,我倾向于防御性地编写代码以防止类似的事情。

有什么方法可以创建这个 id 而不必在每次插入新行时查询今年的最大 id?

想法:

  • A CreateNewInvoiceSP,它获取MAX那一年的值(令人讨厌)
  • 一些神奇的内置功能可以做到这一点(我可以做梦)
  • 能够在IDENTITYorDEFAULT声明中指定一些 UDF 或其他内容(??)
  • 使用的视图PARTITION OVER + ROW()(删除会出现问题)
  • 一个触发器INSERT(仍然需要运行一些MAX查询:()
  • 一年一度的后台工作,更新了一张表格,其中插入了每年的 MAX,然后我......什么?!

所有这些都有些不理想。欢迎任何想法或变化!

gbn*_*gbn 17

您的领域有 2 个元素

  • 一个自动递增的数字

它们不需要存储为一个字段

例子:

  • 具有默认值的年份列 YEAR(GETDATE())
  • 基于序列的数字列。

然后创建一个连接它们的计算列(使用适当的格式)。序列可以在年份变化时重置。

SQLfiddle 中的示例代码:*(SQLfiddle 并不总是有效)

-- Create a sequence
CREATE SEQUENCE CountBy1
    START WITH 1
    INCREMENT BY 1 ;

-- Create a table
CREATE TABLE Orders
    (Yearly int NOT NULL DEFAULT (YEAR(GETDATE())),
    OrderID int NOT NULL DEFAULT (NEXT VALUE FOR CountBy1),
    Name varchar(20) NOT NULL,
    Qty int NOT NULL,
    -- computed column
    BusinessOrderID AS RIGHT('000' + CAST(Yearly AS VARCHAR(4)), 4)
                     + RIGHT('00000' + CAST(OrderID AS VARCHAR(6)), 6),
    PRIMARY KEY (Yearly, OrderID)
    ) ;


-- Insert two records for 2015
INSERT INTO Orders (Yearly, Name, Qty)
    VALUES
     (2015, 'Tire', 7),
     (2015, 'Seat', 8) ;


-- Restart the sequence (Add this also to an annual recurring 'Server Agent' Job)
ALTER SEQUENCE CountBy1
    RESTART WITH 1 ;

-- Insert three records, this year.
INSERT INTO Orders (Name, Qty)
    VALUES
     ('Tire', 2),
     ('Seat', 1),
     ('Brake', 1) ;
Run Code Online (Sandbox Code Playgroud)


Liy*_*sky 8

您是否考虑过使用种子 = 2016000000 创建身份字段?

 create table Table1 (
   id bigint identity(2016000000,1),
   field1 varchar(20)...
)
Run Code Online (Sandbox Code Playgroud)

这个种子应该每年自动增加,例如在 2017/1/1 晚上你需要安排

DBCC CHECKIDENT (Table1, RESEED, 2017000000)
Run Code Online (Sandbox Code Playgroud)

但是我已经看到了设计的问题,例如:如果你有百万条记录怎么办?

  • 另一个问题是记录是否不按时间顺序出现。如果是这种情况,身份可能不是要走的路。 (2认同)