SQL Server SELECT nella tabella esistente


384

Sto cercando di selezionare alcuni campi da una tabella e inserirli in una tabella esistente da una stored procedure. Ecco cosa sto provando:

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

Penso che SELECT ... INTO ...sia per le tabelle temporanee ed è per questo che ottengo un errore che dbo.TableTwoesiste già.

Come posso inserire più righe da dbo.TableOnein dbo.TableTwo?


29
Dato che hai già accettato una risposta, volevo offrire solo una nota: selezionare Into non è "per tabelle temporanee", ma per creare una nuova tabella basata sulla struttura (e sui dati) della porzione selezionata della query . Per una tabella X, puoi selezionarla sempre per un massimo di 1 volta *, dopodiché devi utilizzare Inserisci in per aggiungere dati. * Se la tabella esiste già, quindi zero volte. Questo ovviamente, a meno che non si lasci cadere prima la tabella.
pinkfloydx33,

8
ma tieni presente che Seleziona in non copia i vincoli di indice / chiave primaria / chiave esterna, quindi ti lascia un heap-o-data non indicizzato. È utile per un rapido lavoro di sviluppo, ma non per aggiungere / spostare una vera tabella di produzione.
Graham Griffiths,

basta eseguire questa frase 'drop table tabletwo;' ed eseguire sopra la query. Selezionare ... in non è per le tabelle temporanee.
Shiwangini,

Risposte:


637

SELECT ... INTO ... funziona solo se la tabella specificata nella clausola INTO non esiste, altrimenti devi usare:

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

Questo presuppone che ci siano solo due colonne in dbo.TABLETWO - altrimenti devi specificare le colonne:

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

52
È consigliabile specificare sempre le colonne, indipendentemente dal fatto che siano tutte presenti o meno. Aiuterà a evitare che le cose si rompano quando qualcuno aggiunge una colonna.
HLGEM,

1
Hmm, la SELECT... INTO...dichiarazione non sembra funzionare se la tabella specificata nella INTOclausola non esiste già. Ricevo un errore "variabile non dichiarata". Anche se forse questo problema è solo per MySQL. Il CREATE TABLE ... LIKE .. worked;
LazerSharks,

1
@Gnuey SELECT ... INTO ... funziona solo se esiste una tabella esistente. Se non c'è una tabella esistente, utilizzare il formato del manifesto originale (che sarà creare una nuova tabella)
Will

6
@ Volevi dire il contrario di quello che hai detto? 'SELEZIONA ... INTO ...' richiede una tabella inesistente da specificare, mentre 'INSERISCI INTO ...' richiede una tabella esistente da specificare.
André C. Andersen,

5
Vorrei che ci fosse un contatore per il numero di volte che ricontrollo e uso questa risposta!
MTAdmin,

13

Esistono due modi diversi per implementare l'inserimento di dati da una tabella a un'altra tabella.

Per tabella esistente - INSERIRE IN SELEZIONA

Questo metodo viene utilizzato quando la tabella è già stata creata nel database in precedenza e i dati devono essere inseriti in questa tabella da un'altra tabella. Se le colonne elencate nella clausola insert e la clausola select sono uguali, non è necessario elencarle. È buona norma elencarli sempre per motivi di leggibilità e scalabilità.

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

Per tabella inesistente - SELEZIONA IN

Questo metodo viene utilizzato quando la tabella non è stata creata in precedenza e deve essere creata quando i dati di una tabella devono essere inseriti nella tabella appena creata da un'altra tabella. La nuova tabella viene creata con gli stessi tipi di dati delle colonne selezionate.

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

Rif 1 2


3

Funzionerebbe come indicato di seguito:

insert into Gengl_Del Select Tdate,DocNo,Book,GlCode,OpGlcode,Amt,Narration 
from Gengl where BOOK='" & lblBook.Caption & "' AND DocNO=" & txtVno.Text & ""

5
+1 per contrastare il -1 e per lo sforzo di dare idee che possono essere utilizzate o referenziate da altri utenti. @MarkSowul ha ragione nell'iniezione di SQL, ma per motivi accademici altre persone possono provare quel tipo di metodo.
Albert Laure,

1
Molte tabelle hanno un campo di incremento automatico, che non può essere inserito. Quindi SELECT *non funzionerà. Questo è un modo migliore, grazie!
MJH,

2
@ User6675636b20796f7521 Non vorrei spingermi fino al punto di suggerire che "va bene" per altre persone provare quel tipo di metodo, se si tratta dell'iniezione SQL di cui stiamo parlando. Non dovrebbe mai essere fatto e quindi mai provato. Sarebbe molto più produttivo modificare questa risposta mostrando il modo corretto di farlo fin dall'inizio, e se qualcuno chiede: "che cosa hanno i punti interrogativi / ai simboli?" rispondi semplicemente, "quelli sono marcatori di parametri da usare nelle query con parametri (fuori campo)" e lasciali capire da lì.
Matt Borja,

2
select *
into existing table database..existingtable
from database..othertables....

Se hai select * into tablename from other tablenamesgià usato , la prossima volta, per aggiungere, diciselect * into existing table tablename from other tablenames


2
PS Testato su SYBASE ASE 15.5
Verena_Techie

10
L'OP chiede MS SQL.
GrandMasterFlush,

1

Se la tabella di destinazione esiste ma non si desidera specificare i nomi delle colonne:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.