SQL Server SELECT na tabela existente

384

Estou tentando selecionar alguns campos de uma tabela e inseri-los em uma tabela existente de um procedimento armazenado. Aqui está o que estou tentando:

SELECT col1, col2
INTO dbo.TableTwo 
FROM dbo.TableOne 
WHERE col3 LIKE @search_key

Eu acho que SELECT ... INTO ...é para tabelas temporárias e é por isso que recebo um erro que dbo.TableTwojá existe.

Como posso inserir várias linhas de dbo.TableOneem dbo.TableTwo?

Daniel
fonte
29
Como você já aceitou uma resposta, gostaria de oferecer apenas uma observação: Selecionar em não é "para tabelas temporárias", é para criar uma nova tabela com base na estrutura (e dados) da parte selecionada da consulta . Para uma tabela X, você só pode selecionar uma vez no máximo 1 vez *, depois disso é necessário usar a opção Inserir para anexar quaisquer dados. * Se a tabela já existir, zero vezes. Isso é claro, a menos que você derrube a tabela primeiro.
pinkfloydx33
8
mas observe que a opção Selecionar em não copia restrições de índice / chave primária / chave estrangeira; portanto, você recebe um heap-o-data não indexado. É útil para o trabalho rápido do desenvolvedor, mas não é a maneira de adicionar / mover uma tabela de produção real.
Graham Griffiths
basta executar esta instrução 'drop table tabletwo;' e execute a consulta acima. Selecione ... em não é para tabelas temporárias.
Shiwangini 13/07/19

Respostas:

637

SELECT ... INTO ... só funciona se a tabela especificada na cláusula INTO não existir - caso contrário, você deverá usar:

INSERT INTO dbo.TABLETWO
SELECT col1, col2
  FROM dbo.TABLEONE
 WHERE col3 LIKE @search_key

Isso pressupõe que há apenas duas colunas no dbo.TABLETWO - você precisará especificar as colunas caso contrário:

INSERT INTO dbo.TABLETWO
  (col1, col2)
SELECT col1, col2
  FROM dbo.TABLEONE
 WHERE col3 LIKE @search_key
Pôneis OMG
fonte
52
É uma prática recomendada sempre especificar as colunas, independentemente de elas estarem todas lá ou não. Isso ajudará a impedir que as coisas quebrem quando alguém adiciona uma coluna.
HLGEM
11
Hmm, a SELECT... INTO...instrução parece não funcionar se a tabela especificada na INTOcláusula ainda não existir. Estou recebendo um erro "variável não declarada". Embora talvez esse problema seja apenas para o MySQL. O CREATE TABLE ... LIKE .. worked;
LazerSharks 07/07
11
@Gnuey SELECT ... INTO ... só funciona se houver uma tabela existente. Se não houver uma tabela existente, use o formato do autor original (que vai criar uma nova tabela)
Will
6
@ Will Você quis dizer o contrário do que disse? 'SELECT ... INTO ...' requer que uma tabela inexistente seja especificada, enquanto 'INSERT INTO ...' requer que uma tabela existente seja especificada.
André C. Andersen
5
Eu gostaria que houvesse um contador para o número de vezes que eu volto e uso esta resposta!
MTAdmin
13

Existem duas maneiras diferentes de implementar a inserção de dados de uma tabela para outra.

Para tabela existente - INSERT INTO SELECT

Este método é usado quando a tabela já foi criada no banco de dados anteriormente e os dados devem ser inseridos nessa tabela a partir de outra tabela. Se as colunas listadas na cláusula insert e select forem iguais, não será necessário listá-las. É uma boa prática sempre listá-los para fins de legibilidade e escalabilidade.

----Create testable
CREATE TABLE TestTable (FirstName VARCHAR(100), LastName VARCHAR(100))
----INSERT INTO TestTable using SELECT
INSERT INTO TestTable (FirstName, LastName)
SELECT FirstName, LastName
FROM Person.Contact
WHERE EmailPromotion = 2
----Verify that Data in TestTable
SELECT FirstName, LastName
FROM TestTable
----Clean Up Database
DROP TABLE TestTable

Para tabela não existente - SELECT INTO

Este método é usado quando a tabela não é criada anteriormente e precisa ser criada quando os dados de uma tabela devem ser inseridos na tabela recém-criada de outra tabela. A nova tabela é criada com os mesmos tipos de dados que as colunas selecionadas.

----Create a new table and insert into table using SELECT INSERT
SELECT FirstName, LastName
INTO TestTable
FROM Person.Contact
WHERE EmailPromotion = 2
----Verify that Data in TestTable
SELECT FirstName, LastName
FROM TestTable
----Clean Up Database
DROP TABLE TestTable

Ref 1 2

Somnath Muluk
fonte
3

Funcionaria como indicado abaixo:

insert into Gengl_Del Select Tdate,DocNo,Book,GlCode,OpGlcode,Amt,Narration 
from Gengl where BOOK='" & lblBook.Caption & "' AND DocNO=" & txtVno.Text & ""
Vinod Pareek
fonte
5
+1 para neutralizar o -1 e para o esforço de fornecer idéias que possam ser usadas ou referenciadas por outros usuários. O @MarkSowul tem razão na injeção de SQL, mas, para fins acadêmicos, outras pessoas podem tentar esse tipo de método.
Albert Laure
11
A maioria das tabelas possui um campo de incremento automático, que não pode ser inserido. Então SELECT *não vai funcionar. Esta é uma maneira melhor, obrigado!
MJH
2
@ User6675636b20796f7521 Eu não chegaria a sugerir que não há problema em outras pessoas tentarem esse tipo de método, se é sobre a injeção de SQL que estamos falando. Isso nunca deve ser feito e, portanto, nunca deve ser tentado. Seria muito mais produtivo editar essa resposta, mostrando a maneira correta de fazer isso desde o início, e se alguém perguntar: "o que há com os pontos de interrogação / símbolos?" você simplesmente responde "esses são marcadores de parâmetros para uso em consultas parametrizadas (fora do escopo)" e permite que eles descubram a partir daí.
Matt Borja
2
select *
into existing table database..existingtable
from database..othertables....

Se você já usou select * into tablename from other tablenames, da próxima vez, para acrescentar, você dizselect * into existing table tablename from other tablenames

Verena_Techie
fonte
2
PS Testado em SYBASE ASE 15.5
Verena_Techie
10
O OP está pedindo pelo MS SQL.
GrandMasterFlush
1

Se a tabela de destino existir, mas você não desejar especificar os nomes das colunas:

DECLARE @COLUMN_LIST NVARCHAR(MAX);
DECLARE @SQL_INSERT NVARCHAR(MAX);

SET @COLUMN_LIST = (SELECT DISTINCT
    SUBSTRING(
        (
            SELECT ', table1.' + SYSCOL1.name  AS [text()]
            FROM sys.columns SYSCOL1
            WHERE SYSCOL1.object_id = SYSCOL2.object_id and SYSCOL1.is_identity <> 1
            ORDER BY SYSCOL1.object_id
            FOR XML PATH ('')
        ), 2, 1000)
FROM
    sys.columns SYSCOL2
WHERE
    SYSCOL2.object_id = object_id('dbo.TableOne') )

SET @SQL_INSERT =  'INSERT INTO dbo.TableTwo SELECT ' + @COLUMN_LIST + ' FROM dbo.TableOne table1 WHERE col3 LIKE ' + @search_key
EXEC sp_executesql @SQL_INSERT
slayernoah
fonte