Sql server 创建一个;“持久化计算列”;带有日期、时间和序列值
我想以mmddyyyyhmms0001的模式生成一个自动生成值的列 这里0001是序列值 经过多次搜索,我找到了一个解决办法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)
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;
简单地将当前时间戳和主键列连接在一起会有什么错呢?也许这会有帮助:可能会重复