如何在SQL Server中创建自定义的动态字符串序列

时间:2016-10-23 19:30:17

标签: sql sql-server

有没有办法在SQL Server中动态构建包含日期/字符串/数字的序列?

在我的应用程序中,我希望每个订单都有一个唯一的标识符,它是一个序列:订单类型,年份,月份,递增数字

(例如:NO / 2016/10/001,NO / 2016/10/002)

其中NO =“正常订单”,2016年是一年,10是一个月,001是递增数字。我们的想法是,员工更容易使用这些类型的标识符进行通信(当然这个序列不是数据库表的主键)

我知道我可以创建一个存储过程,将Order类型作为参数并返回序列,但我很好奇是否有更好的方法可以做到。

干杯!

2 个答案:

答案 0 :(得分:1)

您可以在表定义中创建一个计算列,它将数据库中的其他值连接到您要查找的标识符类型。

试试这个简化的例子: -

CREATE TABLE Things ( 
  [Type of Order] varchar(10), 
  [Year] int,
  [Month] int,
  [Inc Number] int identity(1,1),
  [Identifier] as [Type of Order] + '/' + cast([Year] as varchar) + '/' + cast([Month] as varchar) + '/' + cast([Inc Number] as varchar)
)

insert into Things
values
('NO',2016,10)

select * from Things

如果你想做一些更复杂的事情,你总是可以使用触发器来更新列插入或更新。

答案 1 :(得分:1)

IDENTITY列可能存在差距。想象一下插入物是出于任何原因而退回......

您可以使用ROW_NUMBER() OVER(PARTITION BY CONVERT(VARCHAR(6),OrderDate,112) ORDER BY OrderDate)来开始每月从1开始的排序编号。什么是最好的取决于以下问题:是否有并行插入操作?

由于此订单名称应该是唯一的,您可能会遇到 unique-key-violation ,您需要使用复杂的机制来解决...

如果您可以使用现有ID,则可以将标量函数与计算列一起使用(可能会声明为persistant):

CREATE TABLE OrderType(ID INT,Name VARCHAR(100),Abbr VARCHAR(2));
INSERT INTO OrderType VALUES(1,'Normal Order','NO')
                           ,(2,'Special Order','SO');
GO
CREATE FUNCTION dbo.OrderCaption(@OrderTypeID INT,@OrderDate DATETIME,@OrderID INT)
RETURNS VARCHAR(100)
AS
BEGIN
    RETURN ISNULL((SELECT Abbr FROM OrderType WHERE ID=@OrderTypeID),'#NA')
         + '/' + CAST(YEAR(@OrderDate) AS VARCHAR(4))
         + '/' + REPLACE(STR(MONTH(@OrderDate),2),' ','0')
         + '/' + REPLACE(STR(@OrderID,5),' ','0')
END
GO


CREATE TABLE YourOrder
(
     ID INT IDENTITY
    ,OrderDate DATETIME DEFAULT(GETDATE())
    ,OrderTypeID INT NOT NULL --foreign key...
    ,Caption AS dbo.OrderCaption(OrderTypeID,OrderDate,ID)
);
GO

INSERT INTO YourOrder(OrderDate,OrderTypeID)
VALUES({ts'2016-01-01 23:23:00'},1)
     ,({ts'2016-02-02 12:12:00'},2)
     ,(GETDATE(),1);
GO

SELECT * FROM YourOrder

结果

ID  OrderDate               OrderTypeID     Caption
1   2016-01-01 23:23:00.000      1          NO/2016/01/00001
2   2016-02-02 12:12:00.000      2          SO/2016/02/00002
3   2016-10-23 23:16:23.990      1          NO/2016/10/00003