2016-11-07 52 views
1

獲取以下錯誤:(第21行是聲明語句)。標識插入 - 錯誤消息

Msg 544, Level 16, State 1, Procedure insert_employee_details, Line 21
Cannot insert explicit value for identity column in table 'DB_Actions' when IDENTITY_INSERT is set to OFF.

這是我曾嘗試:

SET IDENTITY_INSERT DB_Actions ON; 

但後來我得到這個錯誤:

Msg 8107, Level 16, State 1, Line 31
IDENTITY_INSERT is already ON for table 'StacysDB.dbo.Employee_Details'. Cannot perform SET operation for table 'DB_Actions'.

這不會使得感知到我。首先它不起作用,因爲身份插入關閉。然後,當我嘗試打開它時,它已經打開了。

我知道這是一個常見的錯誤,所以我嘗試了一個確認的解決方案,在插入值之前重新創建表並設置標識插入,然後返回並插入值,但我得到了相同的錯誤(Msg 8107)。

感謝您的任何幫助。

--1 
--CREATE TABLE DB_Actions 
--(
--Id numeric(5,0) IDENTITY(1,1) PRIMARY KEY, 
--Table_Name varchar(20), 
--Action_Name varchar(10), 
--User_Name varchar(50), 
--Done_ON datetime, 
--Record_Id numeric(5,0) 
--); 

--2 
--INSERT TRIGGER 
--CREATE TRIGGER insert_employee_details 
--ON Employee_Details 
--FOR INSERT 
--AS 
--DECLARE @id int, @name varchar(20) 
--SELECT @id = Emp_Id, @name = Emp_First_Name FROM inserted 
--INSERT INTO DB_Actions(Id, Table_Name, Action_Name, User_Name, 
    --Done_ON, Record_Id) 
--VALUES(@id, 
    -- 'Employee_Details', 
    -- 'INSERT', 
    -- @name, 
    -- getdate(), 
    -- @id 
--); 


INSERT INTO Employee_Details(Emp_Id, Emp_First_Name, Emp_Middle_Name, Emp_Last_Name, Emp_Address1, Emp_Address2, Emp_Country_Id, Emp_State_Id, Emp_City_Id, Emp_Zip, Emp_Mobile, Emp_Gender, Desig_Id, Emp_DOB, Emp_JoinDate, Emp_Active) 
VALUES(9000, 'A', 'B', 'C', 'D', 'E', 2, 3, 4, 44444, 4444444, 1, 3333, getdate(), getdate(), 0); 
+0

我也讀過斷開和重新連接可以工作。但事實並非如此。 –

+0

在這裏稍微退一步,你是否真的需要'Id'作爲一個'IDENTITY'列呢?它看起來像某種類型的審計表,爲什麼不把它變成一個普通的「INT」列呢? – DavidG

+0

它需要是身份和主鍵。我試圖刪除我的插入聲明中的Id列,但無法讓它工作 –

回答

0

IDENTITY_INSERT選項並不打算用於您的日常處理。 IDENTITY_INSERT僅作爲臨時解決方法。例如,您需要還原意外刪除的值。如果您必須將顯式值插入標識字段作爲日常處理的一部分,則必須重新考慮解決方案。

實現此目的的最簡單方法是將顯式值存儲在另一個字段中,並將標識保留給要管理的SQL Server。在您的解決方案中,這意味着從觸發器插入語句中刪除DB_Actions.ID字段(您已經在record_id中存儲了ID)。

此外,插入的表可以返回多個記錄,因此您不應該嘗試將其存儲在單個變量中。而是使用select語句插入。這也將使你的代碼更具可讀性。

因此,如下解決這個問題改變你的觸發:

CREATE TRIGGER insert_employee_details 
ON Employee_Details 
FOR INSERT 
AS 

INSERT INTO DB_Actions(Table_Name, Action_Name, User_Name, Done_ON, Record_Id) 
SELECT 'Employee_Details', 'INSERT', Emp_First_Name, getdate(), Emp_Id 
FROM inserted; 

如果你的SQL Server 2012或更高版本,另一種解決方案是使用SEQUENCE對象,而不是身份。 SEQUENCE爲您提供了更大的靈活性,並解決了許多身份屬性問題。

另請注意,DB_Actions中的User_Name字段可能是用於執行操作的系統用戶,而不是表中的員工姓名(您始終可以通過查詢帶有記錄標識的原始表來獲取後者)。因此,不要考慮Emp_First_Name字段,請考慮使用USER_NAME()內置的函數。

+0

我同意這是幫助重新設計架構的所有有用和必要的建議,我們被要求提供「任何幫助」,但這實際上並沒有回答爲什麼無法設置IDENTITY_INSERT的問題。正如Murthy所述,此功能一次只能爲一個表設置,並且已經爲Employee_Details表設置,因此無法爲DB_Actions表打開。也許你可以在你的回答中加入一些關於這個的東西 –

+0

@DavidDubois,IDENTITY_INSERT選項並不打算用於日常的處理。 IDENTITY_INSERT僅作爲臨時解決方法。例如,您需要還原意外刪除的值。如果您發現自己必須將顯式值插入標識字段作爲常規處理的一部分,則需要重新考慮解決方案。我昨天絕對同意 – under

+0

。 –