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?


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

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


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 & ""

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


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
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.