Sql server 创建一个;“持久化计算列”;带有日期、时间和序列值

Sql server 创建一个;“持久化计算列”;带有日期、时间和序列值,sql-server,Sql Server,我想以mmddyyyyhmms0001的模式生成一个自动生成值的列 这里0001是序列值 经过多次搜索,我找到了一个解决办法 CREATE SEQUENCE [dbo].[BikePartIdHelper] AS [int] START WITH 1 INCREMENT BY 1 MINVALUE 0 MAXVALUE 2147483647 CACHE GO CREATE TABLE [dbo].[BikeParts] ( [ID] [INT] IDENTITY(1,1)

我想以mmddyyyyhmms0001的模式生成一个自动生成值的列

这里0001是序列值

经过多次搜索,我找到了一个解决办法

CREATE SEQUENCE [dbo].[BikePartIdHelper] 
AS [int]
START WITH 1
INCREMENT BY 1
MINVALUE 0
MAXVALUE 2147483647
CACHE 
GO    

CREATE TABLE [dbo].[BikeParts]
(
    [ID] [INT] IDENTITY(1,1) NOT NULL,
    [BikeParts_GUID]  AS ((REPLACE(CONVERT([VARCHAR](10), GETDATE(),(101)), '/', '') + REPLACE(CONVERT([VARCHAR], GETDATE(), (8)), ':', '')) + RIGHT(REPLICATE('0', (4)) + CONVERT([VARCHAR], [BikePart_ID]), (4))) PERSISTED,
    [BikePart_ID] [INT] NOT NULL,
    [BikePart_Name] [VARCHAR](100) NULL,

    CONSTRAINT [PK_BikeParts] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[BikeParts] 
    ADD DEFAULT (NEXT VALUE FOR [dbo].[BikePartIdHelper]) FOR [BikePart_ID]
GO
但是我从这个代码中得到了这个错误:

味精4936,第16级,状态1,第11行
无法持久化表“BikeParts”中的计算列“BikeParts\u GUID”,因为该列不确定

如果我删除持久化,代码工作正常,但在这种情况下,它将在每个select语句中生成新值,因此我需要将其设置为持久化

如果有任何替代方案可以解决生成列值的目的,则无需使用计算列作为mmddyyyhhmms0001


我真的非常感谢任何类型的帮助。

列定义没有持久化的原因是它依赖于
GetDate()
,这是一个非确定性函数(确定性函数在任何时候使用相同的输入调用它时都会返回相同的值,其他任何东西都是非确定性的)

但是,有一个解决方法-您可以向表中添加另一列,该列的默认值为
GetDate()
,并将计算列建立在该列的基础上

在我这样做的同时,我还随意简化了代码,并将默认约束命名为
BikePart\u ID
列(最佳实践是始终命名约束)

以下代码在Rexstester上进行了测试,似乎运行良好:

CREATE SEQUENCE [dbo].[BikePartIdHelper] 
AS [int]
    START WITH 1
    INCREMENT BY 1
    MINVALUE 0
    MAXVALUE 2147483647
    CACHE 
GO    

CREATE TABLE [dbo].[BikeParts]
(
    [ID] [INT] IDENTITY(1,1) NOT NULL,
    [BikeParts_GUID] AS 
        REPLACE(CONVERT(CHAR(10), BikePart_CreateDate, 101), '/', '') + 
        REPLACE(CONVERT(CHAR(8), BikePart_CreateDate, 114), ':', '') + 
        RIGHT('0000' + CAST([BikePart_ID] As VARCHAR(4)), 4) PERSISTED,
    [BikePart_ID] [INT] NOT NULL CONSTRAINT DF_BikePart_ID DEFAULT (NEXT VALUE FOR [dbo].[BikePartIdHelper]),
    [BikePart_Name] [VARCHAR](100) NULL,
    [BikePart_CreateDate] DateTime CONSTRAINT DF_BikePart_CreateDate DEFAULT(GETDATE())

    CONSTRAINT [PK_BikeParts] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

另一个要考虑的事情——如果您只在计算列中使用4位数字,则没有顺序使序列高于9999——也可以在命中MAX值之后定义它进行循环。

< P>为DATA值添加一个用“代码> GETDATE())的列。作为默认值,并在计算的持久列中使用该列

create table T
(
  ID int identity primary key,
  Created datetime not null default getdate(),
  PersistedID as replace(
                 replace(
                 replace(convert(varchar(19), Created, 126), 
                 '-', ''), 
                 'T', ''), 
                 ':', '') + 
                 right('0000' + convert(varchar(4), ID), 4)
                 persisted
);


go

insert into T default values;

go

select *
from T;

简单地将当前时间戳和主键列连接在一起会有什么错呢?也许这会有帮助:可能会重复