Невозможно вставить явное значение для столбца идентификаторов в таблице 'table', когда для IDENTITY_INSERT установлено значение OFF


361

У меня есть ошибка ниже, когда я выполняю следующий скрипт. В чем заключается ошибка и как ее можно устранить?

Insert table(OperationID,OpDescription,FilterID)
values (20,'Hierachy Update',1)

Ошибка:

Сервер: Msg 544, Уровень 16, Состояние 1, Линия 1

Невозможно вставить явное значение для столбца идентификаторов в таблице «таблица», если для параметра IDENTITY_INSERT установлено значение OFF.



2
@HimanshuAhuja Этот вопрос (1334012) 10 лет, тот, который вы связали только 1. Если что-то, то более новый является дубликатом. Но при ближайшем рассмотрении вы увидите, что они различаются (более новый указывает IDENTITY_INSERT как ON). Пожалуйста, удалите ваш флаг / комментарий.
Джейси

@jasie сделает это, поскольку я не помню, когда я разместил этот флаг
Himanshu Ahuja

Ответы:


467

Вы вводите значения для OperationIdэтого столбца идентичности.

Вы можете включить вставку идентификатора в таблицу таким образом, чтобы указать свои собственные значения идентификаторов.

SET IDENTITY_INSERT Table1 ON

INSERT INTO Table1
/*Note the column list is REQUIRED here, not optional*/
            (OperationID,
             OpDescription,
             FilterID)
VALUES      (20,
             'Hierachy Update',
             1)

SET IDENTITY_INSERT Table1 OFF 

14
+1 точно - включите опцию , чтобы разрешить явные вставки ON , а затем вставить, затем включите опцию OFF снова
marc_s

13
Если вы действительно хотите добавить свое значение в столбец идентификаторов, это ваш ответ, но, с другой стороны, кто-то установил увеличение столбца при вставке. В этом случае таблица будет отслеживать следующий свободный номер, и вам не нужно будет генерировать OperationID самостоятельно. Новый идентификатор можно получить с помощью SELECT SCOPE_IDENTITY ().
Хакан Винтер

15
Опасная практика, не рекомендуйте использовать ее без предостережений, объясняющих, почему это плохая идея. Очень плохой ответ.
HLGEM

7
хороший ответ, но убедитесь, что вы знаете, что делаете. Для меня полезно заполнить базу данных данными, в которых внешние ключи должны совпадать по разным таблицам
Берти

2
@UlyssesAlves: эта опция может быть включена только для одной таблицы всей базы данных - поэтому, если вы оставите ее для одной таблицы, вы никогда не сможете использовать ее для другой таблицы. Кроме того: это не та опция, которую следует оставить включенной - по умолчанию вы должны разрешить SQL Server обрабатывать значения идентификаторов - это предназначено только в качестве крайней меры для очень специфических случаев - не универсальная опция, которую следует включать или выключать в ваш отдых ...
marc_s

61

не присваивайте значение OperationID, потому что оно будет сгенерировано автоматически. попробуй это:

Insert table(OpDescription,FilterID) values ('Hierachy Update',1)

5
это правильный ответ, если вы хотите автоматически сгенерированный OperationID
shaijut

46

Просто Если вы получаете эту ошибку на сервере SQL, запустите этот запрос:

SET IDENTITY_INSERT tableName ON

это работает только одна таблица базы данных, например, если имя таблицы является студентом, запрос выглядит так SET IDENTITY_INSERT student ON

Если вы получаете эту ошибку в своем веб-приложении или используете Entity Framework, сначала запустите этот запрос на SQL-сервере и обновите вашу Entity Model ( .edmx file) и постройте свой проект, и эта ошибка будет устранена.


Это было так в моем веб-приложении MVC с EF, и я просто удалил модель из .edmx и заново добавил (Обновление модели правой кнопкой мыши из базы данных) и очистил и перестроил проект, который затем работал для меня. Спасибо @Уманг Патва
Ишвор Ханал

42

Будьте очень осторожны при установке IDENTITY_INSERT на ON. Это плохая практика, если база данных не находится в режиме обслуживания и не настроена для одного пользователя. Это влияет не только на вашу вставку, но и на тех, кто пытается получить доступ к таблице.

Почему вы пытаетесь поместить значение в поле идентичности?


5
Влияет как? Это опция уровня сеанса, а не свойство таблицы.
Мартин Смит

5
Однократная синхронизация данных между двумя базами данных, которые вы хотите поддерживать отношения. Например, я использовал его, чтобы вытащить мою схему продукта из одной базы данных в другую
NSjonas

1
@NSjonas, это было бы неплохо использовать set Identity _insert table1 ON. Я видел людей, которые хотели использовать это, чтобы сделать что-то из приложения, что должно быть сделано с помощью простой вставки и создания идентификатора.
HLGEM

2
Вопрос «Можете ли вы указать, что это такое и как это можно решить?» Ваш ответ - это комментарий, который вызывает предупреждение и другой вопрос вместо правильного ответа, который решает проблему.
Качественный катализатор

да, не вставляйте значение в первичный ключ.
Дофламинго

22

Есть в основном 2 разных способа вставить записи без ошибки:

1) Когда IDENTITY_INSERT установлен на OFF. ПЕРВИЧНЫЙ КЛЮЧ «ИД» НЕ ДОЛЖЕН БЫТЬ НАСТОЯЩИМ

2) Когда IDENTITY_INSERT включен. ПЕРВИЧНЫЙ КЛЮЧ «ИД» ДОЛЖЕН БЫТЬ НАСТОЯЩИМ

Согласно следующему примеру из той же таблицы, созданной с ИДЕНТИЧНЫМ КЛЮЧОМ:

CREATE TABLE [dbo].[Persons] (    
    ID INT IDENTITY(1,1) PRIMARY KEY,
    LastName VARCHAR(40) NOT NULL,
    FirstName VARCHAR(40)
);

1) В первом примере вы можете вставить новые записи в таблицу, не получая ошибки, когда IDENTITY_INSERT выключен. ПЕРВИЧНЫЙ КЛЮЧ «ИД» не должен присутствовать от отчетности «Вставить в» и уникальное значение идентификатора будет добавлено автоматически: . Если в этом случае присутствует идентификатор из INSERT, вы получите сообщение об ошибке «Невозможно вставить явное значение для столбца идентификации в таблице ...»

SET IDENTITY_INSERT [dbo].[Persons] OFF;
INSERT INTO [dbo].[Persons] (FirstName,LastName)
VALUES ('JANE','DOE'); 
INSERT INTO Persons (FirstName,LastName) 
VALUES ('JOE','BROWN');

ВЫХОД ТАБЛИЦЫ [dbo]. [Персоны] будет:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) Во втором примере вы можете вставить новые записи в таблицу, не получая ошибки, когда IDENTITY_INSERT включен. ПЕРВИЧНЫЙ КЛЮЧ «ИД» ДОЛЖЕН БЫТЬ ПРИСУТСТВУЕТ из операторов «ВСТАВИТЬ В», если значение ИД еще не существует : если в этом случае ИД НЕ присутствует в ВСТАВКЕ, вы получите ошибку «Явное значение должно быть указано для таблицы идентификаторов столбца ... »

SET IDENTITY_INSERT [dbo].[Persons] ON;
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (5,'JOHN','WHITE'); 
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (3,'JACK','BLACK'); 

ВЫХОД ТАБЛИЦЫ [dbo]. [Персоны] будет:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE
3     BLACK      JACK
5     WHITE      JOHN

2
Плюс один для объяснения того, как работает флаг. Спас мой день Супермен
Джон

20

В вашей сущности для этой таблицы добавьте DatabaseGeneratedатрибут над столбцом, для которого установлена ​​вставка идентификатора:

Пример:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskId { get; set; }

Ну, правда, но я действительно хотел получить ответ для EF :-) Тем не менее, он не подходит для ОП, который, возможно, никогда не использовал или, возможно, даже не сталкивался с EF.
Auspex

В любом случае ответ неверный. Моя сущность уже указана с DatabaseGeneratedOption.Identity, и я все еще получаю ошибку. Это моя вина, я помещаю псевдо-идентификаторы в новые строки, чтобы отличать их друг от друга на моей веб-странице, и я надеюсь, что просто обнулять их до того, как insertбудет достаточно.
Auspex

13

Вы можете просто использовать это утверждение, например, если ваша таблица называется Школа . Перед введением УБЕДИТЕСЬ IDENTITY_INSERT установлен в положение ON и после вставки запроса поворота IDENTITY_INSERT OFF

SET IDENTITY_INSERT School ON
/*
  insert query
  enter code here
*/
SET IDENTITY_INSERT School OFF

1
Не могли бы вы немного расширить свой ответ, включив в него объяснение команды, почему она работает и как она влияет?
gareththegeek

@gareththegeek да, это для идентификатора столбца, вы должны убедиться, что это сделать для вставки данных.

6

Если вы используете liquibase для обновления вашего SQL Server, вы, вероятно, пытаетесь вставить ключ записи в поле autoIncrement. После удаления столбца из вставки ваш скрипт должен запуститься.

<changeSet id="CREATE_GROUP_TABLE" >
    <createTable tableName="GROUP_D">
        <column name="GROUP_ID" type="INTEGER" autoIncrement="true">
            <constraints primaryKey="true"/>
        </column>
    </createTable>
</changeSet>

<changeSet id="INSERT_UNKNOWN_GROUP" >
    <insert tableName="GROUP_D">    

        <column name="GROUP_ID" valueNumeric="-1"/>
 ...
    </insert>
</changeSet>

4

В вашем запросе есть упомянутый OperationId, которого не должно быть, поскольку он автоматически увеличивается

Insert table(OperationID,OpDescription,FilterID)
values (20,'Hierachy Update',1)

так что ваш запрос будет

Insert table(OpDescription,FilterID)
values ('Hierachy Update',1)

3

Другая ситуация состоит в том, чтобы проверить, что первичный ключ имеет то же имя, что и у ваших классов, где единственное отличие состоит в том, что к первичному ключу добавлен «ID», или указать [Key] для первичных ключей, которые не связаны с тем, как класс назван.


2
  1. Это происходит, когда у вас есть столбец (Первичный ключ), для которого в SQL не установлено значение Is Identity, равное true, и вы не передаете его явное значение во время вставки. Он займет первую строку, затем вы не сможете вставить вторую строку, появится ошибка. Это можно исправить, добавив эту строку кода [DatabaseGenerated(DatabaseGeneratedOption.Identity)]в столбец PrimaryKey и убедитесь, что для него задан тип данных int . Если столбец является первичным ключом и для IsIDentity в SQL задано значение true, в этой строке кода нет необходимости[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. это также происходит, когда у вас есть столбец, который не является первичным ключом, в SQL, для которого установлено значение Is Identity в значение true, а в EF вы не добавили эту строку кода [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Спасибо, это было исправлением, которое я часами искал.
Vishav Premlall

2

Лучшее решение - использовать аннотацию GeneratedValue(strategy = ...), т.е.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column ...
private int OperationID;

он говорит, что этот столбец генерируется базой данных, используя стратегию IDENTITY, и вам не нужно заботиться - база данных сделает это.


1

Если у вас возникла эта проблема при использовании sql-сервера с sequelize-typescript npm, обязательно добавьте @AutoIncrementв столбец ID:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

0

И если вы используете Oracle SQL Developer для подключения, не забудьте добавить / sqldev: stmt /

/ sqldev: stmt / установить identity_insert TABLE в;


Ясно, что это не тот случай, у вопроса есть тег «sql-server»
DanielV

0

Я не уверен, что использовать для «Вставка таблицы», но если вы просто пытаетесь вставить некоторые значения, попробуйте:

Insert Into [tablename] (OpDescription,FilterID)
values ('Hierachy Update',1);

У меня было такое же сообщение об ошибке, но я думаю, что это должно работать. Идентификатор должен автоматически увеличиваться до тех пор, пока это первичный ключ.


0

Я решил эту проблему, создавая новый объект каждый раз, когда я хочу добавить что-либо в базу данных.


0

Обратите внимание, что если вы закрываете каждую строку ;, SET IDENTITY_INSERT mytable ONкоманда не будет выполняться для следующих строк.

т.е.
запрос как

SET IDENTITY_INSERT mytable ON;
INSERT INTO mytable (VoucherID, name) VALUES (1, 'Cole');

Выдает ошибку
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF.

Но такой запрос будет работать:

SET IDENTITY_INSERT mytable ON
INSERT INTO mytable (VoucherID, name) VALUES (1, 'Cole')
SET IDENTITY_INSERT mytable OFF;

Кажется, что SET IDENTITY_INSERTкоманда выполняется только для транзакции, и она ;будет означать конец транзакции.


-1

Проблема возникает из-за использования нетипизированного DBContext или DBSet, если вы используете интерфейс и реализуете метод сохранения изменений общим способом.

Если это ваш случай, я предлагаю, например, строго типизированный DBContex

MyDBContext.MyEntity.Add(mynewObject)

тогда .Savechangesбудет работать


-1

Просто удалите таблицы, которые перетаскиваются в файл .dbml, и снова перетащите их. Затем Очистить решение> Восстановить решение> Построить решение.

Вот что сработало для меня.

Я не сделал таблицу самостоятельно, я использовал VS и SSMS, я перешел по этой ссылке для идентификации ASP.NET: https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/ добавление-САШИ-идентичность к ан-пустому или существовавшему-веб-форм-проект

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.