2016-11-07 4 views
1

Получение следующей ошибки: (строка 21 - инструкция объявления).Identity Insert- сообщение об ошибке

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

он должен быть идентификационным и первичным ключом. Ive попытался исключить столбец Идентификатор в моей инструкции вставки, но не смог заставить его работать –

ответ

0

IDENTITY_INSERT опция не предназначена для использования в повседневной работе. IDENTITY_INSERT означает только временное обходное решение. Например, вам нужно восстановить значения, которые были случайно удалены. Если вам нужно вставить явные значения в поле идентификации как часть вашей обычной обработки, вам нужно переосмыслить свое решение.

Самый простой способ добиться этого - сохранить явные значения в другом поле и оставить идентификатор для SQL-сервера для управления. В вашем решении это означало бы удаление поля DB_Actions.ID из инструкции триггера insert (вы уже сохраняете ID в record_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 или более поздней версии, альтернативное решение будет использовать объект ПОСЛЕДОВАТЕЛЬНОСТИ вместо идентичности. ПОСЛЕДОВАТЕЛЬНОСТЬ дает вам больше гибкости и решает много проблем с идентификационным свойством.

Обратите внимание, что поле User_Name в DB_Actions, вероятно, предназначено для пользователя системы, выполняющего действие, а не из имени сотрудника из таблицы (вы всегда можете получить последнее, запросив исходную таблицу с идентификатором записи). Поэтому вместо поля Emp_First_Name рассмотрим возможность использования USER_NAME() встроенной функции.

+0

Я согласен, что это все полезные и необходимые советы, чтобы помочь перепроектировать архитектуру, и нас попросили «любую помощь», но на самом деле это не отвечает на вопрос о том, почему IDENTITY_INSERT не может быть установлен. Как упоминалось Murthy, это можно установить только для одной таблицы за раз, и она уже настроена для таблицы Employee_Details и поэтому не может быть включена для таблицы DB_Actions. Возможно, вы могли бы добавить что-то об этом к своему ответу. –

+0

@DavidDubois, параметр IDENTITY_INSERT не предназначен для использования в вашей повседневной обработке. IDENTITY_INSERT означает только временное обходное решение. Например, вам нужно восстановить значения, которые были случайно удалены. Если вам приходится вставлять явные значения в поле идентификации как часть вашей обычной обработки, вам нужно переосмыслить свое решение. – under

+0

вчера, я абсолютно согласен. –