Como ativar e desativar o IDENTITY_INSERT usando o SQL Server 2008?

461

Por que estou recebendo um erro ao inserir quando IDENTITY_INSERT está desativado?

Como ativá-lo corretamente no SQL Server 2008? É usando o SQL Server Management Studio?

Eu executei esta consulta:

SET IDENTITY_INSERT Database. dbo. Baskets ON

Em seguida, recebi a mensagem de volta no console de que os comandos foram concluídos com êxito. No entanto, quando executo o aplicativo, ele ainda gera o erro mostrado abaixo:

Cannot insert explicit value for identity column in table 'Baskets' when 
IDENTITY_INSERT is set to OFF.
Principiante
fonte
Expanda esta pergunta para que possamos entender o que você está tentando fazer. Que declaração você está executando quando encontrou esse erro e qual é o texto real da mensagem de erro?
Matt Gibson
Mesmo que você tenha feito outra pergunta, você deve aceitar uma resposta aqui: respondemos o que você pediu .
gbn 15/08/11
8
Tenho horror da ideia de que alguém está tentando enviar valores de identidade de um aplicativo. Isso não é algo que você deve fazer, exceto a migração de dados pouco frequente. Se você estiver fazendo isso regularmente o suficiente para executá-lo em um aplicativo, provavelmente precisará revisitar o design da sua tabela.
HLGEM #
Estou usando isso no meu backup com script SQL. Durante a restauração, deixe-me carregar os dados em uma tabela com incremento automático com valores originais. O backup com script me permitiu fazer o downgrade do banco de dados SQL. A realização do backup por script do Management Studio cria um script descarregável se eu armazenar dados binários em um campo de texto.
Jettero 8/03/2017

Respostas:

771

Via SQL conforme MSDN

SET IDENTITY_INSERT sometableWithIdentity ON

INSERT INTO sometableWithIdentity 
    (IdentityColumn, col2, col3, ...)
VALUES 
    (AnIdentityValue, col2value, col3value, ...)

SET IDENTITY_INSERT sometableWithIdentity OFF

A mensagem de erro completa informa exatamente o que está errado ...

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

gbn
fonte
@ Iniciante: você é, portanto, daí o erro. Como sabemos que você não deseja inserir valores? Temos apenas uma mensagem de erro
gbn 15/08
3
Erro é do meu aplicativo quando eu faço DB.SaveChanges ();
Iniciante
5
Não, basta parar de enviar um valor para a coluna de identidade. Ou defina-o se desejar no seu aplicativo, se desejar enviar um valor ..... mas por que uma coluna com a propriedade de identidade está configurada para gerar valores? Não podemos decidir por você
gbn 15/08
22
@Beginner: A configuração é aplicável apenas na sessão atual (ninguém apontou isso para esta pergunta); portanto, seu aplicativo precisaria ativá-lo para que ele executasse essas inserções (e provavelmente é melhor ativar imediatamente novamente quando essas inserções são concluídas, como shows de gbn). Como você inseriu um valor na coluna de identidade sem perceber que isso não está claro, mas talvez versões mais antigas do SQL Server o incluam implicitamente em todas as colunas quando colunas de inserção explícitas não são especificadas (?), Como Ismael parece sugerir.
Rob Parker
2
@ Rob, acho que você tem um ponto e eu pessoalmente falho na revisão de código em qualquer código que não seja inserido sem especificar colunas. Além do tempo perdido em um erro, essa é uma prática arriscada e você pode acabar com sérios problemas de integridade de dados se os dados da coluna não corresponderem corretamente.
HLGEM #
59

Eu tive um problema em que ele não me permitiu inseri-lo mesmo depois de definir o IDENTITY_INSERT ON.

O problema era que eu não especifiquei os nomes das colunas e, por algum motivo, ele não gostou.

INSERT INTO tbl Values(vals)

Então, basicamente faça o INSERT INTO completo tbl (cols) Valores (vals)

Ismael
fonte
6
não faça perguntas no painel de respostas.
Duk
4
isso foi exatamente o que queria de mim, para especificar a lista de colunas (duas colunas sobre a mesa, blá)
Maslow
36

Importação: você deve escrever colunas na INSERTinstrução

INSERT INTO TABLE
SELECT * FROM    

Não está correto.

Insert into Table(Field1,...)
Select (Field1,...) from TABLE

Está correto

R.Alonso
fonte
2
Obrigado, isso foi muito útil
José Romero
1
Se você tiver colunas idênticas em ambas as tabelas, poderá fazê-lo sem listar as colunas no select (Campo1 ..) como este .... Insira na Tabela (Campo1, ...) Selecione * da TABELA ... e se você tiver Campo de identidade para inserir primeiro do ** SET IDENTITY_INSERT Table_name ON
user3590235 4/18/18
@ user3590235 Essa é uma suposição arriscada, que a lista de colunas é idêntica. Fora das consultas manuais do usuário, nunca faça isso, porque garanto que você quebrará o PROD um dia quando outra pessoa modificar a definição da tabela sem atualizar sua referência.
Elaskanator
5

Eu sei que esse é um tópico mais antigo, mas acabei de me deparar com isso. Se o usuário estiver tentando executar inserções na coluna Identity após outra sessão, defina IDENTITY_INSERT ON, então ele provavelmente receberá o erro acima.

A configuração do valor de inserção de identidade e os comandos subsequentes de inserção de DML devem ser executados na mesma sessão.

Aqui, o @Beginner estava configurando o Identity Insert ON separadamente e, em seguida, executando as inserções do aplicativo. É por isso que ele obteve o erro abaixo:

Cannot insert explicit value for identity column in table 'Baskets' when 
IDENTITY_INSERT is set to OFF.
um ok
fonte
0

Provavelmente, quando você tem um campo PRIMARY KEY e está inserindo um valor duplicado ou com o sinalizador INSERT_IDENTITY definido como ativado

seanyp20001
fonte
0

Parece necessário colocar um SET IDENTITY_INSERT Database.dbo.Baskets ON;antes de cada SQLINSERT lote de envio .

Você pode enviar vários INSERT ... VALUES ...comandos iniciados com umSET IDENTITY_INSERT ... ON; sequência no início. Apenas não coloque nenhum separador de lote entre eles.

Não sei por que as SET IDENTITY_INSERT ... ONparadas param de funcionar após o bloco de envio (por exemplo: .ExecuteNonQuery()em C #). Eu tive que colocar SET IDENTITY_INSERT ... ON;novamente no início da próxima seqüência de comando SQL.

Jettero
fonte
talvez isso responda à sua pergunta: stackoverflow.com/questions/5791941/…
Demetris Leptos
0

Outra opção é onde você tem tabelas como 'type' ou 'status', por exemplo, OrderStatus, onde você sempre deseja controlar o valor do Id, crie a coluna Id (Chave Primária) sem que seja uma coluna Identity.

Robert Brooker
fonte
-1

Você precisa adicionar o comando 'go' depois de definir a inserção de identidade. Exemplo:

SET IDENTITY_INSERT sometableWithIdentity ON
go

INSERT sometableWithIdentity (IdentityColumn, col2, col3, ...)
VALUES (AnIdentityValue, col2value, col3value, ...)

SET IDENTITY_INSERT sometableWithIdentity OFF
go
Bruce
fonte
5
Esta pergunta tem quatro anos e tem uma resposta aceita. Sua resposta duplica a resposta aceita
Ghost
13
Bem, não é uma duplicação exata - ele fez incluem o "go" comandos ...;)
RoastBeast