0

我對SQL很陌生。我在這裏有一個問題,我不能創建一個外鍵引用主鍵,這個主鍵是帶有前綴(S0001,S0002等等)的自動增量。無法使用自動增量和前綴創建對主鍵的外鍵引用

這是我的SQL查詢

CREATE TABLE Staff 
(
    No int NOT NULL IDENTITY (1,1), 
    Staff_ID AS 'S' + RIGHT('000' + CAST(No as varchar(10)), 3) PERSISTED, 

    CONSTRAINT PK_Staff PRIMARY KEY CLUSTERED (Staff_ID), 

    Staff_Name varchar(30), 
    Staff_Username varchar(30), 
    Staff_Password varchar(30), 
    Staff_Email varchar(30), 
); 

CREATE TABLE Manager 
(
    No int NOT NULL IDENTITY (1,1), 
    Staff_ID AS 'S' + RIGHT('000' + CAST(No as varchar(10)),3), 

    CONSTRAINT FK_Staff_ID FOREIGN KEY (Staff_ID) REFERENCES Staff(Staff_ID) ON DELETE CASCADE, 

    Manager_Name varchar (30), 
    Manager_Email varchar (30), 
); 

正如你所看到的,我創建了2個表StaffManager,我想創建一個外鍵Manager引用Staff.Staff_ID 。但最終它返回我與此錯誤消息:

消息1764,級別16,狀態1,行1
計算列「Staff_ID」表「經理」是在「外鍵約束」的使用無效因爲它沒有持續下去。
消息1750,級別16,狀態0,行1
無法創建約束。查看以前的錯誤。

我已經嘗試添加PERSISTEDManager查詢,它能夠創建一個Manager表,但是當我在值手動鍵,返回我的錯誤消息。

CREATE TABLE Manager 
(
    No int NOT NULL IDENTITY (1,1), 
    Staff_ID AS 'S' + RIGHT('000' + CAST(No as varchar(10)),3) PERSISTED, 

    CONSTRAINT FK_Staff_ID FOREIGN KEY (Staff_ID) REFERENCES Staff(Staff_ID) ON DELETE CASCADE, 

    Manager_Name varchar (30), 
    Manager_Email varchar (30), 
); 

手動插入值

INSERT INTO Manager (Staff_ID,Manager_Name,Manager_Email) 
VALUES ('S002','Kelvin','[email protected]') 

和錯誤信息就出來了。

消息271,級別16,狀態1,行1
列「Staff_ID」不能被修改,因爲它可以是一個計算列或是UNION運算符的結果。

任何方式來解決這個問題?

+0

爲什麼你需要引用** computed **列?你爲什麼不添加一個對'IDENTITY'列'no'的引用...... – 2014-11-05 17:26:00

+0

既然'Staff_ID'是一個**計算**列,當然,你**不能**插入顯式值到它!你需要在'no'中插入一個值(或者讓'IDENTITY'機制完成它的工作)並且'Staff_ID'的值將自動**爲你設置 – 2014-11-05 17:28:48

+0

將'PERSISTED'添加到'Manager.Staff_ID '列使得這項工作在SQL Server 2012上很好...... – 2014-11-05 17:30:37

回答

1

您無法爲計算字段插入值。插入時不使用下一個標識:

INSERT INTO Manager (Manager_Name, Manager_Email) 
VALUES ('Kelvin', '[email protected]') 

如果要指定字段,您需要指定它所基於的值,即標識字段。您可以使用identity_insert setting重寫身份:

set identity_insert Manager on 

INSERT INTO Manager (No, Manager_Name, Manager_Email) 
VALUES (2, 'Kelvin', '[email protected]') 

set identity_insert Manager off 
+0

是的,我知道我們不能在計算列中插入值。示例:我添加了INSERT INTO Staff(Staff_Name,Staff_Username,Staff_Password,Staff_Email) VALUES('Kelvin','kelvin123','abc123','[email protected]')'由於Staff_ID是自動遞增的該ID是S001。但如果我按照自己的方式在**經理**表中添加** Staff_ID **,則表示它將爲Kelvin生成新的** Staff_ID **,而不是遵循**中的原始** Staff_ID **工作人員**表是S001。 – 2014-11-05 18:57:01

+0

@ChuahChengJun:'經理'表不認爲'Staff'表中的id是一個原始的,它有它自己的'No'和'Staff_ID'字段,它們不依賴於'Staff'中的字段表。如果您希望'經理'表中的'否'字段與'職員'表中的記錄相同,您必須重寫身份並插入特定值。然而,在這種情況下,我認爲你應該重新考慮在表之間鬆散匹配的主鍵,而不是使用普通的外鍵。 – Guffa 2014-11-05 19:09:48

+0

好的,謝謝你們。我只是想出了它,它正在按照我的期望工作。 :) – 2014-11-06 16:57:53

0

不需要指定INSERT語句中的計算列

試試這個

INSERT INTO Manager (Manager_Name,Manager_Email) 
VALUES ('Kelvin','[email protected]') 

它會自動計算並插入到價值staff_Id