No se puede insertar un valor explícito para la columna de identidad en la tabla 'tabla' cuando IDENTITY_INSERT está establecido en OFF

361

Tengo el siguiente error cuando ejecuto el siguiente script. ¿De qué se trata el error y cómo se puede resolver?

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

Error:

Servidor: Msg 544, Nivel 16, Estado 1, Línea 1

No se puede insertar un valor explícito para la columna de identidad en la tabla 'tabla' cuando IDENTITY_INSERT está establecido en OFF.

Martin Clayton
fuente
1
Posible duplicado del error
Himanshu Ahuja
2
@HimanshuAhuja Esta pregunta (1334012) tiene 10 años, la que usted solo ha vinculado 1. En todo caso, la más nueva es un duplicado. Pero al mirar más de cerca, verás que difieren (el más nuevo especifica IDENTITY_INSERT como ON). Por favor, elimine su bandera / comentario.
jasie 01 de
@jasie lo hará, ya que no recuerdo cuando había publicado esta bandera
Himanshu Ahuja

Respuestas:

467

Estás insertando valores para OperationIdeso es una columna de identidad.

Puede activar la inserción de identidad en la tabla de esta manera para que pueda especificar sus propios valores de identidad.

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 
pjp
fuente
14
1 exactamente - a su vez la opción de permitir inserciones explícitas EN , a continuación, insertar, a continuación, a su vez la opción OFF de nuevo
marc_s
13
Si realmente desea agregar su valor a la columna de identidad, esta es su respuesta, pero por otro lado, alguien ha configurado la columna para que se incremente por sí sola al insertarla. En ese caso, la tabla hará un seguimiento del siguiente número libre, y no necesita generar el OperationID usted mismo. SELECT SCOPE_IDENTITY () puede obtener el nuevo ID.
Hakan Winther
15
Práctica peligrosa, no recomiendo usarlo sin advertencias explicando por qué es una mala idea. Muy mala respuesta.
HLGEM
77
buena respuesta, pero asegúrese de saber lo que está haciendo. Para mí es útil sembrar una base de datos con datos donde las claves foráneas deben coincidir en diferentes tablas
Berty
2
@UlyssesAlves: esta opción solo se puede activar para una sola tabla en toda la base de datos, por lo que si la deja activada para una tabla, nunca podrá usarla para otra tabla. Además: no es una opción que deba dejarse activada; de manera predeterminada, debe permitir que SQL Server maneje los valores de identidad; esto solo pretende ser una medida de último recurso para casos muy específicos; no es una opción de propósito general para dejar activada o desactivada en tu ocio ...
marc_s
61

no ponga valor a OperationID porque se generará automáticamente. prueba esto:

Insert table(OpDescription,FilterID) values ('Hierachy Update',1)
Wael Dalloul
fuente
55
esta es la respuesta correcta si desea OperationID generado automáticamente
shaijut
46

Simplemente, si obtiene este error en el servidor SQL, ejecute esta consulta:

SET IDENTITY_INSERT tableName ON

esto funciona solo en una sola tabla de base de datos, por ejemplo, si el nombre de la tabla es estudiante, la consulta se verá así SET IDENTITY_INSERT student ON

Si obtiene este error en su aplicación web o usa el marco de la entidad, primero ejecute esta consulta en el servidor SQL y actualice su modelo de entidad ( .edmx file) y cree su proyecto y este error se resolverá

Umang Patwa
fuente
Fue el caso en mi aplicación web MVC con EF y acabo de eliminar el modelo de .edmx y lo volví a agregar (haga clic con el botón derecho Actualizar modelo de la base de datos) y limpie y reconstruya el proyecto que luego funcionó para mí. Gracias @Umang Patwa
Ishwor Khanal
42

Tenga mucho cuidado de establecer IDENTITY_INSERT en ON. Esta es una mala práctica a menos que la base de datos esté en modo de mantenimiento y configurada para un solo usuario. Esto afecta no solo a su inserción, sino a las de cualquier otra persona que intente acceder a la tabla.

¿Por qué estás tratando de poner un valor en un campo de identidad?

HLGEM
fuente
55
Afecta de qué manera? Esta es una opción de nivel de sesión, no una propiedad de la tabla.
Martin Smith
55
Sincronización de datos única entre dos bases de datos con las que desea mantener relaciones. Por ejemplo, lo usé para extraer el esquema de mi producto de una base de datos a otra
NSjonas
1
@NSjonas, sería un buen uso de set Identity _insert table1 ON. He visto personas que querían usar esto para hacer algo desde la aplicación que debería hacerse con una simple inserción y permitir que se genere la identidad.
HLGEM
2
La pregunta es "¿Podría especificar qué es y cómo se puede resolver?" Su respuesta es un comentario que genera una advertencia y otra pregunta en lugar de una respuesta adecuada que aborde el problema.
Catalizador de calidad
Sí, no inserte valor en la clave primaria.
doflamingo
22

Básicamente, hay 2 formas diferentes de INSERTAR registros sin tener un error:

1) Cuando IDENTITY_INSERT está desactivado. LA "ID" PRINCIPAL DE LA CLAVE NO DEBE ESTAR PRESENTE

2) Cuando IDENTITY_INSERT está activado. LA "ID" PRINCIPAL DE LA CLAVE DEBE ESTAR PRESENTE

Según el siguiente ejemplo de la misma tabla creada con una CLAVE PRIMARIA DE IDENTIDAD:

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

1) En el primer ejemplo, puede insertar nuevos registros en la tabla sin obtener un error cuando IDENTITY_INSERT está desactivado. La clave primaria "ID" no debe estar presente desde los estados "INSERT INTO" y un valor único de identificación se añadirá automáticamente: . Si la ID está presente desde INSERT en este caso, obtendrá el error "No se puede insertar un valor explícito para la columna de identificación en la tabla ..."

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

SALIDA de la TABLA [dbo]. [Personas] será:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) En el segundo ejemplo, puede insertar nuevos registros en la tabla sin obtener un error cuando IDENTITY_INSERT está activado. La "ID" PRINCIPAL DE LA CLAVE DEBE ESTAR PRESENTE en las declaraciones "INSERT INTO" siempre que el valor de ID no exista : si la ID NO está presente desde INSERT en este caso, obtendrá el error "El valor explícito debe ser especificado para la tabla de columnas de identidad ... "

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

SALIDA de la TABLA [dbo]. [Personas] será:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE
3     BLACK      JACK
5     WHITE      JOHN
Especialista en control de calidad
fuente
2
Más uno para explicar realmente cómo funciona la bandera. Salvó mi día Superman
John
20

En su entidad para esa tabla, agregue el DatabaseGeneratedatributo encima de la columna para la que se establece la inserción de identidad:

Ejemplo:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskId { get; set; }
usuario902490
fuente
Bueno, es cierto, pero realmente quería una respuesta para EF :-) Aún así, no es apropiado para el OP que puede que nunca haya usado, o quizás incluso encontrado, EF.
Auspex
En cualquier caso, la respuesta es incorrecta. Mi entidad ya está especificada DatabaseGeneratedOption.Identityy sigo recibiendo el error. Es mi culpa, estoy colocando pseudo-ID en las nuevas filas para distinguirlos unos de otros en mi página web, y espero simplemente anularlos antes de que insertsea ​​suficiente.
Auspex
13

simplemente puede usar Esta declaración, por ejemplo, si el nombre de su tabla es Escuela . Antes de la inserción Asegúrese de que identity_insert se establece en EN y después de la inserción consulta a su vez identity_insert OFF

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

fuente
1
¿Podría ampliar un poco su respuesta para incluir una explicación del comando, por qué funciona y qué efecto tiene?
gareththegeek
@gareththegeek sí, es para la columna de identidad que debe asegurarse de insertar para insertar datos.
6

Si está utilizando liquibase para actualizar su SQL Server, es probable que esté intentando insertar una clave de registro en un campo autoIncrement. Al eliminar la columna de la inserción, su script debería ejecutarse.

<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>
iowatiger08
fuente
4

Hay OperationId previamente mencionado en su consulta que no debería estar allí, ya que se autoincreamenta

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

entonces su consulta será

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

Otra situación es verificar que la Clave primaria sea el mismo nombre que con sus clases, donde la única diferencia es que su clave primaria tiene una 'ID' adjunta o especificar [Clave] en las claves primarias que no están relacionadas con cómo se nombra la clase

salemsky95
fuente
2
  1. Esto ocurre cuando tiene una columna (Clave primaria) que no está establecida en Is Identity to true en SQL y no pasa su valor explícito durante la inserción. Tomará la primera fila, luego no podrá insertar la segunda fila, aparecerá el error. Esto se puede corregir agregando esta línea de código [DatabaseGenerated(DatabaseGeneratedOption.Identity)]en su columna PrimaryKey y asegúrese de que esté establecida en un tipo de datos int . Si la columna es la clave principal y se establece en IsIDentity en verdadero en SQL, no es necesaria esta línea de código[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. Esto también ocurre cuando tiene una columna que no es la clave principal, en SQL que se establece en Is Identity to true, y en su EF no agregó esta línea de código [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
Siphamandla Hero Ngwenya
fuente
Gracias, esta fue la solución que pasé horas buscando.
Vishav Premlall
2

La mejor solución es usar anotaciones GeneratedValue(strategy = ...), es decir

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

dice, que esta columna es generada por la base de datos usando la estrategia IDENTITY y no necesita ocuparse de eso, la base de datos lo hará.

Tomasz Dzięcielewski
fuente
1

Si tiene este problema mientras usa un servidor sql con el secuencialize-typecript npm, asegúrese de agregarlo @AutoIncrementa la columna ID:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;
Kate Kasinskaya
fuente
0

Y si está utilizando Oracle SQL Developer para conectarse, recuerde agregar / sqldev: stmt /

/ sqldev: stmt / set identity_insert TABLE en;

Hao Deng
fuente
Claramente este no es el caso, la pregunta tiene una etiqueta "sql-server"
DanielV
0

No estoy seguro de cuál es el uso de la "Insertar tabla", pero si solo está intentando insertar algunos valores, intente:

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

Me apareció el mismo mensaje de error, pero creo que esto debería funcionar. La ID debería incrementarse automáticamente automáticamente siempre que sea una clave principal.

Mateo
fuente
0

Resolví este problema creando un nuevo objeto cada vez que quiero agregar algo a la base de datos.

Naresh Bisht
fuente
0

Tenga en cuenta que si está cerrando cada línea con ;, el SET IDENTITY_INSERT mytable ONcomando no se mantendrá para las siguientes líneas.

es decir,
una consulta como

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

Da el error
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF.

Pero una consulta como esta funcionará:

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

Parece que el SET IDENTITY_INSERTcomando solo se cumple para una transacción, y ;significará el final de una transacción.

cryanbhu
fuente
-1

El problema surgió del uso de DBContext o DBSet no tipado si usa la interfaz e implementa el método de guardar cambios de forma genérica

Si este es su caso, propongo escribir DBContex fuertemente por ejemplo

MyDBContext.MyEntity.Add(mynewObject)

entonces .Savechangesfuncionará

Mostafa Basha
fuente