获得以下错误:(第21行是声明语句)。
消息544,级别16,状态1,过程insert_employee_details,第21行
无法在表格中插入标识列的显式值' DB_Actions'当IDENTITY_INSERT设置为OFF时。
以下是我的尝试:
SET IDENTITY_INSERT DB_Actions ON;
但后来我收到了这个错误:
Msg 8107,Level 16,State 1,Line 31
执行SET操作
对于表' StacysDB.dbo.Employee_Details',IDENTITY_INSERT已经开启。无法对表格' DB_Actions'。
这对我来说并不合适。首先它不起作用,因为身份插入是关闭的。然后,当我试图打开它时,它已经开启了。
我知道这是一个常见的错误所以我尝试了一个确认的解决方案,重新创建表并在插入值之前将身份插入设置为on,然后返回关闭并插入值,但我得到了相同的错误(消息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)
IDENTITY_INSERT选项不适用于您的日常处理。 IDENTITY_INSERT仅用作临时解决方法。例如,您需要恢复意外删除的值。如果您必须在常规处理过程中将显式值插入标识字段,则必须重新考虑您的解决方案。
实现此目的的最简单方法是将显式值存储在另一个字段中,并将标识保留给SQL服务器进行管理。在您的解决方案中,这将意味着从触发器插入语句中删除DB_Actions.ID字段(您已经在record_id中存储了ID)。
此外,inserted表可以返回多个记录,因此您不应该尝试将其存储在单个变量中。而是使用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字段可能适用于执行操作的系统用户,而不是表中的员工姓名(您始终可以通过查询具有记录ID的原始表来获取后者)。因此,考虑使用内置函数的USER_NAME()而不是Emp_First_Name字段。