Eu tenho uma tabela com coluna de identidade diga:
create table with_id (
id int identity(1,1),
val varchar(30)
);
É bem conhecido, que este
select * into copy_from_with_id_1 from with_id;
resulta em copy_from_with_id_1 com identidade no id também.
A seguinte pergunta de estouro de pilha menciona a listagem de todas as colunas explicitamente.
Vamos tentar
select id, val into copy_from_with_id_2 from with_id;
Ops, mesmo neste caso id é uma coluna de identidade.
O que eu quero é uma mesa como
create table without_id (
id int,
val varchar(30)
);
De livros on-line
Abaixo da página:
Então... teoricamente você poderia se safar com:
Seria importante comentar este código para explicá-lo, para que ele não seja removido na próxima vez que alguém olhar para ele.
Inspirado na resposta de Erics, encontrei a seguinte solução que depende apenas dos nomes das tabelas e não usa nenhum nome de coluna específico:
Editar
É até possível melhorar isso para
Você pode usar uma junção para criar e preencher a nova tabela de uma só vez:
Devido à
1 = 0
condição, o lado direito não terá correspondências e, portanto, evitará a duplicação das linhas do lado esquerdo e, como essa é uma junção externa, as linhas do lado esquerdo também não serão eliminadas. Por fim, por se tratar de uma junção, a propriedade IDENTITY é eliminada.Selecionar apenas as colunas do lado esquerdo, portanto, produzirá uma cópia exata de dbo.TableWithIdentity somente em termos de dados, ou seja, com a propriedade IDENTITY removida.
Tudo isso dito, Max Vernon levantou um ponto válido em um comentário que vale a pena ter em mente. Se você observar o plano de execução da consulta acima:
você notará que a tabela de origem é mencionada no plano de execução apenas uma vez. A outra instância foi eliminada pelo otimizador.
Portanto, se o otimizador puder estabelecer corretamente que o lado direito da junção não é necessário no plano, deve ser razoável esperar que em uma versão futura do SQL Server ele possa descobrir que a propriedade IDENTITY não precisa ser removido também, pois não há mais outra coluna IDENTITY na linha de origem definida de acordo com o plano de consulta. Isso significa que a consulta acima pode parar de funcionar conforme o esperado em algum momento.
Mas, como corretamente observado por ypercubeᵀᴹ , até agora o manual tem declarado explicitamente que, se houver uma junção, a propriedade IDENTITY não será preservada:
Portanto, enquanto o manual continuar mencionando isso, provavelmente podemos ter certeza de que o comportamento permanecerá o mesmo.
Parabéns a Shaneis e ypercubeᵀᴹ por trazer um tópico relacionado no chat.
Tente este código..
A
ISNULL
chamada garante que a nova coluna seja criada comNOT NULL
nulidade.Só para mostrar de uma forma diferente:
Você pode usar um servidor vinculado .
Você pode criar temporariamente um servidor vinculado ao servidor local usando isto:
Nesse ponto, você executaria o
select * into
código, referenciando olocalserver
nome de quatro partes do servidor vinculado:Depois que isso for concluído, limpe o
localserver
servidor vinculado com isto:Ou você pode usar a
OPENQUERY
sintaxeA propriedade identity não é transferida se a instrução select contiver uma junção e, portanto,
também dará o comportamento desejado (da
id
coluna copiada para não manter aIDENTITY
propriedade. No entanto, terá o efeito colateral de não copiar nenhuma linha! (como em alguns outros métodos), então você precisará fazer:(obrigado AakashM!)
A maneira mais fácil é tornar a coluna parte de uma expressão.
Exemplo:
Se a tabela dbo.Employee tiver uma identidade na coluna ID, no exemplo abaixo, a tabela temporária #t também terá uma IDENTIDADE na coluna ID.
Altere isso para aplicar uma expressão ao ID e você #t não terá mais uma coluna IDENTITY on ID. Nesse caso, aplicamos uma adição simples à coluna ID.
Outros exemplos de expressões para outros tipos de dados podem incluir: convert (), concatenação de strings ou Isnull ()
Às vezes, você deseja inserir de uma tabela onde você não sabe (ou se importa) se a coluna foi criada usando IDENTITY ou não. Pode até não ser uma coluna inteira com a qual você está trabalhando. Nesse caso, funcionará o seguinte:
ISNULL removerá o atributo IDENTITY da coluna, mas o inserirá com o mesmo nome e tipo da coluna original e também o tornará não anulável. TOP(0) criará uma tabela vazia que você pode usar para inserir linhas selecionadas. Você também pode compactar a tabela antes de inserir dados, se necessário.
removerá a identidade.
A desvantagem é que
id
se torna anulável, mas você pode adicionar essa restrição.Tente a seguinte consulta: Encontrei esta funcionando corretamente. Isso selecionará dados em colunas sem identidade = 1
Você pode obter os detalhes do nome da coluna na tabela sys.columns
Tente a seguinte consulta: