SQL Server SELECT en la tabla existente

384

Estoy tratando de seleccionar algunos campos de una tabla e insertarlos en una tabla existente desde un procedimiento almacenado. Esto es lo que estoy intentando:

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

Creo que SELECT ... INTO ...es para tablas temporales, por eso me sale un error que dbo.TableTwoya existe.

¿Cómo puedo insertar varias filas de dbo.TableOnedentro dbo.TableTwo?

Daniel
fuente
29
Como ya ha aceptado una respuesta, quería ofrecer solo una nota: Seleccionar en no es "para tablas temporales", es para crear una nueva tabla basada en la estructura (y los datos) de la parte seleccionada de la consulta . Para una tabla X, solo puede Seleccionar en ella un máximo de 1 vez *, después de eso debe usar Insertar en para agregar cualquier dato. * Si la tabla ya existe, entonces cero veces. Esto es, por supuesto, a menos que dejes caer la tabla primero.
pinkfloydx33
8
pero tenga en cuenta que Select Into no copia las restricciones de índice / clave principal / clave externa, por lo que le deja un montón de datos no indexados. Es útil para un trabajo de desarrollo rápido, pero no es la forma de agregar / mover una tabla de producción real.
Graham Griffiths
simplemente ejecute esta declaración 'drop table tabletwo;' y ejecuta la consulta anterior. Seleccione ... en no es para tablas temporales.
Shiwangini

Respuestas:

637

SELECT ... INTO ... solo funciona si la tabla especificada en la cláusula INTO no existe; de ​​lo contrario, debe usar:

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

Esto supone que solo hay dos columnas en dbo.TABLETWO: de lo contrario, debe especificar las columnas:

INSERT INTO dbo.TABLETWO
  (col1, col2)
SELECT col1, col2
  FROM dbo.TABLEONE
 WHERE col3 LIKE @search_key
Ponis OMG
fuente
52
Es una buena práctica especificar siempre las columnas sin importar si están todas allí o no. Ayudará a evitar que las cosas se rompan cuando alguien agrega una columna.
HLGEM
1
Hmm, la SELECT... INTO...declaración no parece funcionar si la tabla especificada en la INTOcláusula aún no existe. Recibo un error de "variable no declarada". Aunque tal vez este problema sea solo para MySQL. El CREATE TABLE ... LIKE .. worked;
LazerSharks
1
@Gnuey SELECT ... INTO ... solo funciona si hay una tabla existente. Si no hay una tabla existente, use el formato del póster original (que creará una nueva tabla)
Será
66
@ Will ¿Querías decir lo contrario de lo que dijiste? 'SELECCIONAR ... EN ...' requiere que se especifique una tabla no existente, mientras que 'INSERTAR EN ...' requiere que se especifique una tabla existente.
André C. Andersen
55
¡Ojalá hubiera un contador para la cantidad de veces que reviso y uso esta respuesta!
MTAdmin
13

Hay dos formas diferentes de implementar la inserción de datos de una tabla a otra.

Para la tabla existente: INSERTAR EN SELECCIONAR

Este método se utiliza cuando la tabla ya se creó en la base de datos anteriormente y los datos se deben insertar en esta tabla desde otra tabla. Si las columnas enumeradas en la cláusula de inserción y la cláusula de selección son las mismas, no es necesario que las enumeren. Es una buena práctica enumerarlos siempre con fines de legibilidad y escalabilidad.

----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 tabla no existente - SELECCIONAR EN

Este método se utiliza cuando la tabla no se creó anteriormente y debe crearse cuando los datos de una tabla se insertarán en la tabla recién creada desde otra tabla. La nueva tabla se crea con los mismos tipos de datos que las columnas seleccionadas.

----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
fuente
3

Funcionaría como se indica a continuación:

insert into Gengl_Del Select Tdate,DocNo,Book,GlCode,OpGlcode,Amt,Narration 
from Gengl where BOOK='" & lblBook.Caption & "' AND DocNO=" & txtVno.Text & ""
Vinod Pareek
fuente
55
+1 para contrarrestar el -1 y por el esfuerzo de dar ideas que puedan ser utilizadas o referenciadas por otros usuarios. @ MarkSowul tiene razón en la inyección de SQL, pero por motivos académicos, otras personas pueden probar ese tipo de método.
Albert Laure el
1
La mayoría de las tablas tienen un campo de incremento automático, que no se puede insertar. Entonces SELECT *no funcionará. Esta es una mejor manera, gracias!
MJH
2
@ User6675636b20796f7521 No iría tan lejos como para sugerir que está "bien" que otras personas prueben ese tipo de método, si estamos hablando de la inyección SQL. Nunca se debe hacer y, por lo tanto, nunca se debe intentar. Sería mucho más productivo editar esta respuesta que muestra la forma correcta de hacerlo desde el principio, y si alguien pregunta, "¿qué pasa con los signos de interrogación / en los símbolos?" simplemente responde, "esos son marcadores de parámetros para usar en consultas parametrizadas (fuera de alcance)" y déjelos descifrarlo desde allí.
Matt Borja el
2
select *
into existing table database..existingtable
from database..othertables....

Si ya ha utilizado select * into tablename from other tablenames, la próxima vez, para agregar, digaselect * into existing table tablename from other tablenames

Verena_Techie
fuente
2
PS Probado en SYBASE ASE 15.5
Verena_Techie
10
El OP está pidiendo MS SQL.
GrandMasterFlush
1

Si la tabla de destino existe pero no desea especificar nombres de columna:

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
fuente