Неможливо вставити явне значення стовпця особи в таблицю "table", коли для IDENTITY_INSERT встановлено значення OFF


361

У мене є нижченаведена помилка під час виконання наступного сценарію. У чому полягає помилка та як її можна усунути?

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

Помилка:

Сервер: Msg 544, рівень 16, стан 1, рядок 1

Неможливо вставити явне значення стовпця особи в таблицю "table", коли для IDENTITY_INSERT встановлено значення OFF.



2
@HimanshuAhuja Цьому питанню (1334012) 10 років, тому, з яким ви зв'язали лише 1. Якщо що, то новіший - це дублікат. Але при ближчому розгляді ви побачите, що вони відрізняються (новіший визначає IDENTITY_INSERT як ВКЛ.). Видаліть прапор / коментар.
jasie

@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

Якщо ви отримуєте цю помилку у вашій веб-програмі або ви використовуєте структуру сутності, спочатку запустіть цей запит на SQL сервері та оновіть модель.edmx file вашої сутності ( ) та складіть свій проект, і ця помилка буде усунена


Так було у моєму веб-додатку MVC з EF, і я щойно видалив модель із .edmx та повторно додав (Клацніть правою кнопкою миші оновлення моделі з бази даних) та очистив та відновив проект, який потім працював на мене. Дякую @Umang Patwa
Ishwor Khanal

42

Будьте дуже обережні, щоб встановити IDENTITY_INSERT на УВІМКНЕНО. Це погана практика, якщо база даних не знаходиться в режимі обслуговування та не встановлена ​​для одного користувача. Це впливає не лише на вашу вставку, але й на всіх, хто намагається отримати доступ до таблиці.

Чому ви намагаєтесь ввести значення в поле ідентичності?


5
Яким чином впливає? Це параметр рівня сеансу, а не властивість таблиці.
Мартін Сміт

5
Одноразова синхронізація даних між двома базами даних, з якими потрібно підтримувати зв’язки. Наприклад, я використовував його, щоб перетягувати схему продуктів з однієї бази даних в іншу
NSjonas

1
@NSjonas, це було б добре використовувати встановлений Identity _insert table1 ON. Я бачив людей, які хотіли скористатися цим, щоб зробити щось із програми, що повинно бути виконано простою вставкою і що дозволяє генерувати особистість.
HLGEM

2
Питання "Чи можете ви вказати, що це таке, і як це можна вирішити?" Ваша відповідь - це коментар, який викликає попередження та інше питання замість належної відповіді, яка вирішує проблему.
Якісний каталізатор

так, не вставляйте значення в первинний ключ.
doflamingo

22

В основному є два різних способи ВСТАВИТИ записи без помилки:

1) Якщо значення IDENTITY_INSERT встановлено виключено. ОСНОВНИЙ КЛЮЧ "ІД" НЕ МОЖЕ БУТИ ПРИСТУПАТИ

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

Якщо ви використовуєте liquidibase для оновлення свого SQL-сервера, ви, ймовірно, намагаєтесь вставити ключ запису в поле автоматичного збільшення. Видаливши стовпчик із вставки, ваш сценарій повинен запуститися.

<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

Інша ситуація полягає в тому, щоб перевірити, чи Первинний ключ є тим самим іменем , що і для ваших класів. Єдиною різницею є те, що ваш первинний ключ має 'ідентифікатор', доданий до нього, або вказати [Key] на первинних ключах, які не пов'язані з тим, як клас названий.


2
  1. Це відбувається, коли у вас є стовпчик (Первинний ключ), для якого у SQL не встановлено значення Ідентичність, і ви не передаєте його явне значення під час вставки. Він займе перший рядок, тоді ви не зможете вставити другий ряд, помилка з’явиться. Це можна виправити, додавши цей рядок коду [DatabaseGenerated(DatabaseGeneratedOption.Identity)]у стовпчик PrimaryKey та переконайтесь, що його встановлено до типу даних int . Якщо стовпець є первинним ключем і встановлено значення IsIDentity true у SQL, для цього рядка коду немає необхідності[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. це також відбувається, коли у вас є стовпець, який не є первинним ключем, у SQL, для якого встановлено значення Is Identity, є істина, а у вашому EF ви не додали цей рядок коду [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Дякую, це було виправленням, на які витрачені години шукали годин.
Вішав Премлалл

2

Найкращим рішенням є використання анотації GeneratedValue(strategy = ...), тобто

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

в ньому йдеться про те, що цей стовпець генерується базою даних за допомогою стратегії ІДЕНТИЧНОСТІ, і вам не потрібно дбати - база даних це зробить.


1

Якщо у вас виникає ця проблема під час використання sql-сервера з sequelize-typecript npm, обов’язково додайте @AutoIncrementдо стовпця ID:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

0

І якщо ви використовуєте Oracle SQL Developer для підключення, не забудьте додати / sqldev: stmt /

/ sqldev: stmt / встановити ідентифікатор_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/ додавання-aspnet-ідентичності-до-порожнього-або-існуючого-веб-форм-проекту

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.