2017-08-01 67 views
1

我想为其自定义ID列创建一个包含计算列的表。这是我想要的格式是BID(The Year)-0000例如一个这样的:表'Books'中的计算列'BookID'无法保留,因为该列是非确定性的

BID2017-0001 

我尝试了下面的T-SQL代码,但我得到的非确定性错误。我怎么解决这个问题?

CREATE TABLE Books 
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY, 
BookID AS 'BID'+CAST(YEAR(GETDATE()) as VARCHAR(4))+ RIGHT ('0000' + CAST(ID AS VARCHAR(4)), 4) PERSISTED UNIQUE, 
ISBN VARCHAR(32), 
BookName NVARCHAR(50), 
AuthorName NVARCHAR(50), 
BLanguage VARCHAR(50), 
StaId int, 
StuId int, 
CatNo int); 

我也试过这篇文章,但无法解决问题。 non-deterministic

UPDATE 此外,我需要的一系列'0000'要重置回'0000'新的一年开始的时候。例如,2017年的最后一个ID是'BID2017-0932',当年更改为2018年时我想将ID中的零系列重置为'0000',例如'BID2018-0001'我该如何实现这一目标?

+0

不应它是'的BookID:

ALTER TABLE dbo.Books ADD CreateDate DATETIME NOT NULL CONSTRAINT DF_Books_CreateDate DEFAULT(GETDATE()) GO 

然后我想补充从而计算列VARCHAR(12)'然后当你填充表时使用你的字符串构造? – RealCheeseLord

+0

这不是问题。问题在于导致错误的getdate()函数。 –

+1

所以明年......你想让所有的ID都打勾吗?我对此表示怀疑。在创建记录时,将年份写入记录中的一列。然后,您可以创建该_fixed_(即确定性)值的计算列。 –

回答

1

简单的解决方案

我将因此增加一个CreateDate柱:

ALTER TABLE dbo.Books 
ADD BookID AS ('BID' + LTRIM(YEAR(CreateDate)) + '-' + RIGHT('0000' + LTRIM(ID), 4)) /*PERSISTED*/ 
GO 
+1

谢谢。它为我工作。 –

+0

我更新了问题。你能帮我解决这个问题吗?我无法弄清楚如何解决这个问题。 –

+0

是的,我刚刚读过它。 –

1

你必须在你的代码,这使得列不deterministic.Removing,这将有助于getdate() ..

如果你想知道为什么GETDATE()是nondeterministic.check这里:Is GetDate() deterministic ..

摘录from answer

deterministic意味着该函数在给定相同输入的情况下返回相同的值。在这种情况下,您没有输入,但您始终得到不同的值!系统时钟不是输入,它是函数依赖的外部状态。

+0

我怎样才能得到当年。任何其他功能?正如你所看到的,我需要在id中包含当年的价值。 –

+0

你不能两面都有。要么你有一个持久的计算列,或者你有当年作为它的一部分。我认为这就是答案的要点。 –

+2

@ElhamKohestani - 如果您希望当前年份*在插入行的时间点*,而不是当前查询*时间点*,我认为这很可能,那么您应该将* getdate()的结果存储在另一列(使getdate()成为该列的默认值) –