Impossibile inserire il valore esplicito per la colonna identità nella tabella 'tabella' quando IDENTITY_INSERT è impostato su OFF


361

Ho l'errore di seguito quando eseguo il seguente script. Qual è l'errore e come può essere risolto?

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

Errore:

Server: messaggio 544, livello 16, stato 1, riga 1

Impossibile inserire il valore esplicito per la colonna identità nella tabella 'tabella' quando IDENTITY_INSERT è impostato su OFF.



2
@HimanshuAhuja Questa domanda (1334012) ha 10 anni, quella a cui hai collegato solo 1. Se non altro, il più recente è un duplicato. Ma da vicino vedrai che differiscono (quello più recente specifica IDENTITY_INSERT come ON). Elimina la tua bandiera / commento.
jasie,

@jasie lo farà come non ricordo quando avevo pubblicato questa bandiera
Himanshu Ahuja

Risposte:


467

Stai inserendo valori per OperationIdquello è una colonna di identità.

È possibile attivare l'inserimento dell'identità sulla tabella in questo modo in modo da poter specificare i propri valori di identità.

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 esattamente: attiva l'opzione per consentire l'inserimento esplicito degli inserti , quindi inserisci, quindi disattiva nuovamente l'opzione
marc_s

13
Se vuoi davvero aggiungere il tuo valore alla colonna identità, questa è la tua risposta, ma d'altra parte, qualcuno ha impostato la colonna per incrementare da sola fino all'inserimento. In tal caso, la tabella terrà traccia del prossimo numero gratuito e non sarà necessario generare OperationID da soli. Il nuovo ID può essere recuperato da SELECT SCOPE_IDENTITY ().
Hakan Winther,

15
Pratica pericolosa, sconsigliamo di usarlo senza avvertenze sul perché è una cattiva idea. Risposta molto scarsa.
HLGEM,

7
buona risposta, ma assicurati di sapere cosa stai facendo. Per me è utile eseguire il seeding di un database con dati in cui le chiavi esterne devono corrispondere su tabelle diverse
Berty

2
@UlyssesAlves: questa opzione può essere attivata solo per una singola tabella a livello di database - quindi se la lasci accesa per una tabella, non potrai mai usarla per un'altra tabella. Inoltre: non è un'opzione che dovrebbe essere lasciata attiva - per impostazione predefinita, dovresti lasciare che SQL Server gestisca i valori di identità - questo è inteso solo come misura dell'ultima risorsa per casi molto specifici - non un'opzione per tutti gli usi da lasciare acceso o spento il tuo tempo libero ...
marc_s

61

non assegnare valore a OperationID perché verrà generato automaticamente. prova questo:

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

5
questa è la risposta corretta se si desidera generare OperationID automaticamente
shaijut

46

Semplicemente Se visualizzi questo errore su SQL Server, esegui questa query-

SET IDENTITY_INSERT tableName ON

funziona solo una singola tabella di databse, ad es. Se il nome della tabella è studente, la query avrà il seguente aspetto SET IDENTITY_INSERT student ON

Se ricevi questo errore sulla tua applicazione web o stai usando un framework di entità, prima esegui questa query su SQL server e Aggiorna il tuo modello di entità ( .edmx file) e costruisci il tuo progetto e questo errore verrà risolto


È stato il caso nella mia app Web MVC con EF e ho appena cancellato il modello da .edmx e ri-aggiunto (modello di aggiornamento del clic destro dal database) e pulito e ricostruito il progetto che poi ha funzionato per me. Grazie @Umang Patwa
Ishwor Khanal,

42

Fai molta attenzione a impostare IDENTITY_INSERT su ON. Questa è una pratica scadente a meno che il database non sia in modalità di manutenzione e impostato su singolo utente. Ciò influisce non solo sul tuo inserimento, ma anche su quelli di chiunque cerchi di accedere alla tabella.

Perché stai cercando di inserire un valore in un campo identità?


5
Colpisce in che modo? Questa è un'opzione a livello di sessione non una proprietà della tabella.
Martin Smith,

5
Una volta i dati si sincronizzano tra due database che si desidera mantenere le relazioni. Ad esempio, l'ho usato per estrarre il mio schema di prodotto da un database all'altro
NSjonas

1
@NSjonas, sarebbe un buon uso del set Identity _insert table1 ON. Ho visto persone che volevano usarlo per fare qualcosa dall'applicazione che avrebbe dovuto essere fatto con un semplice inserto e permettendo all'identità di essere generata.
HLGEM,

2
La domanda è "Potresti specificare di cosa si tratta e come può essere risolto?" La tua risposta è un commento che genera un avvertimento e un'altra domanda invece di una risposta corretta che risolve il problema.
Catalizzatore di qualità

sì, non inserire valore nella chiave primaria.
doflamingo,

22

Esistono sostanzialmente 2 modi diversi per INSERIRE i record senza avere un errore:

1) Quando IDENTITY_INSERT è impostato su OFF. L' ID " CHIAVE PRIMARIA " NON DEVE ESSERE PRESENTE

2) Quando IDENTITY_INSERT è impostato su ON. L' ID " CHIAVE PRIMARIA " DEVE ESSERE PRESENTE

Come nell'esempio seguente dalla stessa tabella creata con un IDENTITY PRIMARY KEY:

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

1) Nel primo esempio, è possibile inserire nuovi record nella tabella senza ottenere un errore quando IDENTITY_INSERT è OFF. La chiave primaria "ID" non devono essere presenti dal Bilancio "INSERT INTO" e un valore ID univoco verrà automaticamente aggiunto: . Se l'ID è presente da INSERT in questo caso, verrà visualizzato l'errore "Impossibile inserire il valore esplicito per identificare la colonna nella tabella ..."

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

OUTPUT di TABELLA [dbo]. [Persone] sarà:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) Nel secondo esempio, è possibile inserire nuovi record nella tabella senza ottenere un errore quando IDENTITY_INSERT è ON. L' ID " CHIAVE PRIMARIA " DEVE ESSERE PRESENTE dalle istruzioni "INSERT INTO" fintanto che il valore ID non esiste già : se in questo caso l'ID NON è presente da INSERT, verrà visualizzato l'errore "Il valore esplicito deve essere specificato per la tabella delle colonne di identità ... "

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'); 

OUTPUT di TABELLA [dbo]. [Persone] sarà:

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

2
Più uno per spiegare effettivamente come funziona la bandiera. Mi ha salvato la giornata Superman
John

20

Nella tua entità per quella tabella, aggiungi l' DatabaseGeneratedattributo sopra la colonna per cui è impostato l'inserimento dell'identità:

Esempio:

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

Bene, vero, ma volevo davvero una risposta per EF :-) Tuttavia, non è appropriato per l'OP che potrebbe non aver mai usato, o forse nemmeno incontrato, EF.
Auspex,

In ogni caso, la risposta è sbagliata. La mia entità è già stata specificata con DatabaseGeneratedOption.Identitye continuo a ricevere l'errore. È colpa mia, sto inserendo pseudo-ID nelle nuove righe per distinguerli l'uno dall'altro sulla mia pagina Web e spero semplicemente annullarli prima che insertsia sufficiente.
Auspex,

13

puoi semplicemente usare questa affermazione, ad esempio se il nome della tua tabella è Scuola . Prima di rendere inserimento sicuro IDENTITY_INSERT è impostata su ON e dopo Inserisci query svolta IDENTITY_INSERT OFF

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

1
Potresti espandere leggermente la tua risposta per includere una spiegazione del comando, perché funziona e quale effetto ha?
gareththegeek,

@gareththegeek sì è relativo alla colonna identità, devi assicurarti di inserirla per inserire i dati.

6

Se si utilizza liquibase per aggiornare SQL Server, è probabile che si stia tentando di inserire una chiave record in un campo autoIncrement. Rimuovendo la colonna dall'inserto, lo script dovrebbe essere eseguito.

<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

Nella query è presente OperationId pre-citato che non dovrebbe essere presente poiché viene aumentato automaticamente

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

così sarà la tua domanda

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

3

Un'altra situazione è verificare che la chiave primaria abbia lo stesso nome delle classi in cui l'unica differenza è che alla chiave primaria è stato aggiunto un "ID" o specificare [chiave] su chiavi primarie non correlate al modo in cui la classe è chiamata.


2
  1. Ciò si verifica quando si dispone di una colonna (chiave primaria) che non è impostata su Is Identity su true in SQL e non si passa valore esplicito della stessa durante l'inserimento. Ci vorrà la prima riga, quindi non sarà possibile inserire la seconda riga, verrà visualizzato l'errore. Questo può essere corretto aggiungendo questa riga di codice [DatabaseGenerated(DatabaseGeneratedOption.Identity)]nella colonna PrimaryKey e assicurati che sia impostato su un tipo di dati int . Se la colonna è la chiave primaria ed è impostata su IsIDentity su true in SQL, non è necessario per questa riga di codice[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. questo si verifica anche quando hai una colonna che non è la chiave primaria, in SQL impostato su Is Identity su true e nel tuo EF non hai aggiunto questa riga di codice [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Grazie, questa è stata la soluzione che ho trascorso ore a cercare.
Vishav Premlall,

2

La soluzione migliore è utilizzare l'annotazione GeneratedValue(strategy = ...), ad es

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

dice che questa colonna è generata dal database usando la strategia IDENTITY e non è necessario occuparsene - il database lo farà.


1

Se stai riscontrando questo problema mentre usi un sql-server con il npm sequelize-dattiloscritto assicurati di aggiungere @AutoIncrementalla colonna ID:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

0

E se stai utilizzando Oracle SQL Developer per connetterti, ricorda di aggiungere / sqldev: stmt /

/ sqldev: stmt / set identity_insert TABLE su;


Chiaramente non è così, la domanda ha un tag "sql-server"
DanielV

0

Non sono sicuro di quale sia l'uso per "Inserisci tabella", ma se stai solo cercando di inserire alcuni valori prova:

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

Ho avuto lo stesso messaggio di errore, ma penso che dovrebbe funzionare. L'ID dovrebbe auto-incrementarsi automaticamente purché sia ​​una chiave primaria.


0

Ho risolto questo problema creando un nuovo oggetto ogni volta che volevo aggiungere qualcosa al database.


0

Notare che se si chiude ciascuna riga con ;, il SET IDENTITY_INSERT mytable ONcomando non sarà valido per le righe seguenti.

cioè
una query come

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

Dà l'errore
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF.

Ma una query come questa funzionerà:

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

Sembra che il SET IDENTITY_INSERTcomando valga solo per una transazione e ;significherà la fine di una transazione.


-1

Il problema sollevato dall'utilizzo di DBContext o DBSet non tipizzato se si utilizza Interface e si implementa il metodo di savechanges in modo generico

In questo caso, ad esempio, propongo di scrivere DBContex fortemente tipizzato

MyDBContext.MyEntity.Add(mynewObject)

allora .Savechangesfunzionerà


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.