2017-08-01 41 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()成爲該列的默認值) –