Não é possível inserir um valor explícito para a coluna de identidade na tabela 'table' quando IDENTITY_INSERT está definido como OFF


361

Eu tenho o erro abaixo quando executo o seguinte script. Qual é o erro e como ele pode ser resolvido?

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

Erro:

Servidor: mensagem 544, nível 16, estado 1, linha 1

Não é possível inserir um valor explícito para a coluna de identidade na tabela 'table' quando IDENTITY_INSERT está definido como OFF.



2
@HimanshuAhuja Esta pergunta (1334012) tem 10 anos, a única que você vinculou 1. Se houver, o mais novo é uma duplicata. Mas, olhando mais de perto, você diferirá (o mais novo especifica IDENTITY_INSERT como ON). Exclua sua bandeira / comentário.
Jasie

@jasie vai fazer isso como eu não lembro quando eu tinha postado esta bandeira
Himanshu Ahuja

Respostas:


467

Você está inserindo valores, pois OperationIdé uma coluna de identidade.

Você pode ativar a inserção de identidade na tabela assim para poder especificar seus próprios valores de identidade.

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 exatamente - ativar a opção para permitir inserções explícitas ON , em seguida, inserir, em seguida, ligue a opção OFF novamente
marc_s

13
Se você realmente deseja adicionar seu valor à coluna de identidade, esta é sua resposta, mas, por outro lado, alguém configurou a coluna para aumentar por si mesma na inserção. Nesse caso, a tabela acompanhará o próximo número gratuito e você não precisará gerar o OperationID sozinho. O novo ID pode ser buscado por SELECT SCOPE_IDENTITY ().
Hakan Winther

15
Prática perigosa, não recomendo usá-lo sem ressalvas, dizendo por que é uma má idéia. Resposta muito ruim.
HLGEM 29/03

7
boa resposta, mas saiba o que está fazendo. Para mim, é útil para semear um banco de dados com dados de onde as chaves estrangeiras precisam para igualar-se ao longo de diferentes tabelas
Berty

2
@UlyssesAlves: essa opção pode ser ativada apenas para uma única tabela em todo o banco de dados - portanto, se você a deixar ativada para uma tabela, nunca poderá usá-la para outra tabela. Além disso: não é uma opção que deve ser deixada ativada - por padrão, você deve deixar o SQL Server manipular valores de identidade - destina-se apenas como uma medida de último recurso para casos muito específicos - não é uma opção de uso geral a ser ativada ou desativada em seu lazer ...
marc_s 25/01

61

não coloque valor em OperationID porque ele será gerado automaticamente. tente isto:

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

5
esta é a resposta correta, se você quiser gerado automaticamente operationId
shaijut

46

Simplesmente, se você está recebendo esse erro no SQL Server, execute esta consulta-

SET IDENTITY_INSERT tableName ON

isso está funcionando apenas em uma única tabela de banco de dados, por exemplo, se o nome da tabela for aluno, a consulta será semelhante a esta SET IDENTITY_INSERT student ON

Se você está recebendo esse erro no seu aplicativo da Web ou usando a estrutura da entidade, execute primeiro esta consulta no SQL Server e atualize o modelo da entidade ( .edmx file) e construa seu projeto e esse erro será resolvido


Foi o caso no meu aplicativo da Web MVC com a EF e acabei de excluir o modelo de .edmx e adicioná-lo novamente (clique com o botão direito do mouse em Atualizar modelo do banco de dados) e limpar e reconstruir o projeto que funcionou para mim. Obrigado @Umang Patwa
Ishwor Khanal

42

Tenha muito cuidado ao definir IDENTITY_INSERT como ON. Essa é uma prática ruim, a menos que o banco de dados esteja no modo de manutenção e definido como usuário único. Isso afeta não apenas a sua inserção, mas também as de qualquer outra pessoa tentando acessar a tabela.

Por que você está tentando colocar um valor em um campo de identidade?


5
Afeta de que maneira? Esta é uma opção no nível da sessão, não uma propriedade da tabela.
Martin Smith

5
Sincronização de dados únicos entre dois bancos de dados que você deseja manter relacionamentos. Por exemplo eu usei-a para puxar meu esquema produto de um banco para outro
NSjonas

11
@NSjonas, isso seria um bom uso do conjunto Identity _insert table1 ON. Eu já vi pessoas que queriam usar isso para fazer algo do aplicativo que deveria ser feito com uma inserção simples e permitir que a identidade fosse gerada.
HLGEM

2
A pergunta é "Você pode especificar o que é e como pode ser resolvido?" Sua resposta é um comentário que gera um aviso e outra pergunta em vez de uma resposta adequada que resolva o problema.
Quality Catalyst

sim, não insira valor na chave primária.
Doflamingo

22

Existem basicamente duas maneiras diferentes de INSERIR registros sem ter um erro:

1) Quando o IDENTITY_INSERT está desativado. A CHAVE PRIMÁRIA "ID" NÃO DEVE ESTAR PRESENTE

2) Quando o IDENTITY_INSERT está ativado. A CHAVE PRIMÁRIA "ID" DEVE ESTAR PRESENTE

Conforme o exemplo a seguir da mesma tabela criada com uma CHAVE PRIMÁRIA DE IDENTIDADE:

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

1) No primeiro exemplo, você pode inserir novos registros na tabela sem obter um erro quando o IDENTITY_INSERT estiver desativado. A chave primária "ID" não devem estar presentes nas Demonstrações "INSERT INTO" e um valor de identificação exclusivo será adicionado automaticamente . Se o ID estiver presente no INSERT, nesse caso, você receberá o erro "Não é possível inserir um valor explícito para identificar a coluna na tabela ..."

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

SAÍDA da TABELA [dbo]. [Pessoas] será:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) No segundo exemplo, você pode inserir novos registros na tabela sem obter um erro quando o IDENTITY_INSERT estiver ativado. A PRIMARY KEY "ID" DEVE ESTAR PRESENTE nas instruções "INSERT INTO" desde que o valor da ID ainda não exista : Se a ID NÃO estiver presente na INSERT nesse caso, você receberá o erro "O valor explícito deve ser especificado para a tabela da coluna de identidade ... "

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

SAÍDA da TABELA [dbo]. [Pessoas] será:

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

2
Mais um por realmente explicar como a bandeira funciona. Salvo no dia Superman
John

20

Na sua entidade para essa tabela, adicione o DatabaseGeneratedatributo acima da coluna para a qual a inserção de identidade está definida:

Exemplo:

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

Bem, é verdade, mas eu realmente queria uma resposta para a EF :-) Ainda assim, não é apropriado para o OP que pode nunca ter usado, ou talvez até encontrado, EF.
Auspex

De qualquer forma, a resposta está errada. Minha entidade já está especificada com DatabaseGeneratedOption.Identitye ainda recebo o erro. A culpa é minha, estou colocando pseudo-IDs nas novas linhas para diferenciá-los um do outro na minha página da web e espero simplesmente anulá-los antes que insertseja suficiente.
Auspex

13

você pode simplesmente usar esta declaração, por exemplo, se o nome da sua tabela for Escola . Antes da inserção make certeza identity_insert está definido para ON e depois da inserção consulta vez identity_insert OFF

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

11
Você poderia expandir um pouco sua resposta para incluir uma explicação do comando, por que ele funciona e que efeito tem?
precisa

@gareththegeek sim, é para a coluna de identidade, você precisa inserir os dados.

6

Se você estiver usando o liquibase para atualizar seu SQL Server, provavelmente está tentando inserir uma chave de registro em um campo autoIncrement. Ao remover a coluna da inserção, seu script deve ser executado.

<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

Há OperationId pré-mencionado na sua consulta que não deve estar lá, pois é aumentado automaticamente

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

então sua consulta será

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

3

Outra situação é verificar se a Chave Primária tem o mesmo nome que em suas classes, onde a única diferença é que sua chave primária possui um 'ID' anexado a ela ou especificar [Chave] nas chaves primárias que não estão relacionadas a como o classe é nomeada.


2
  1. Isso ocorre quando você possui uma coluna (Chave primária) que não está definida como Is Identity como true no SQL e não passa um valor explícito durante a inserção. Vai demorar a primeira linha, então você não poderá inserir a segunda linha, o erro será exibido. Isso pode ser corrigido adicionando esta linha de código [DatabaseGenerated(DatabaseGeneratedOption.Identity)]na coluna PrimaryKey e verifique se está definida como um tipo de dados int . Se a coluna for a chave primária e estiver configurada como IsIDentity como true no SQL, não há necessidade dessa linha de código[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. isso também ocorre quando você tem uma coluna que não é a chave primária, no SQL definido como Is Identity como true e no seu EF você não adicionou esta linha de código [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Graças essa foi a correção que iv passou horas procurando.
Vishav Premlall

2

A melhor solução é usar anotação GeneratedValue(strategy = ...), ou seja,

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

diz que esta coluna é gerada pelo banco de dados usando a estratégia IDENTITY e você não precisa cuidar - o banco de dados fará isso.


1

Se você está tendo esse problema ao usar um servidor sql com o npm sequelize-typescript, adicione @AutoIncrementa coluna ID:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

0

E se você estiver usando o Oracle SQL Developer para se conectar, lembre-se de adicionar / sqldev: stmt /

/ sqldev: stmt / define identidade_insira TABELA ativada;


Claramente este não é o caso, a questão tem uma tag "sql-server"
DanielV

0

Não sei ao certo qual é o uso da "Inserir tabela", mas se você estiver apenas tentando inserir alguns valores, tente:

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

Recebi a mesma mensagem de erro, mas acho que isso deve funcionar. O ID deve ser incrementado automaticamente automaticamente, desde que seja uma chave primária.


0

Resolvi esse problema criando um novo objeto toda vez que desejo adicionar algo ao banco de dados.


0

Observe que se você estiver fechando cada linha com ;, o SET IDENTITY_INSERT mytable ONcomando não será válido para as seguintes linhas.

ou seja,
uma consulta como

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

Dá o erro
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF.

Mas uma consulta como esta funcionará:

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

Parece que o SET IDENTITY_INSERTcomando é válido apenas para uma transação, e ;isso significa o fim de uma transação.


-1

O problema foi causado pelo uso de DBContext ou DBSet não digitado, se você usar a Interface e implementar o método de alterações de maneira genérica

Se este for o seu caso, proponho DBContex fortemente tipado, por exemplo

MyDBContext.MyEntity.Add(mynewObject)

então .Savechangesvai funcionar


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.