SQL Server SELECT dans la table existante

384

J'essaie de sélectionner certains champs d'une table et de les insérer dans une table existante à partir d'une procédure stockée. Voici ce que j'essaye:

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

Je pense que SELECT ... INTO ...c'est pour les tables temporaires, c'est pourquoi j'obtiens une erreur qui dbo.TableTwoexiste déjà.

Comment puis-je insérer plusieurs lignes de dbo.TableOnedans dbo.TableTwo?

Daniel
la source
29
Puisque vous avez déjà accepté une réponse, je voulais offrir juste une note: Select Into n'est pas "pour les tables temporaires", c'est pour créer une nouvelle table basée sur la structure (et les données) de la partie sélectionnée de la requête . Pour un tableau X, vous ne pouvez jamais le sélectionner que 1 fois au maximum *, après quoi vous devez utiliser Insérer dans pour ajouter des données. * Si la table existe déjà, alors zéro fois. C'est bien sûr à moins que vous ne déposiez le tableau en premier.
pinkfloydx33
8
mais notez que Select Into ne copie pas les contraintes d'index / clé primaire / clé étrangère, donc il vous laisse un tas de données non indexées. Il est utile pour un travail de développement rapide, mais pas pour ajouter / déplacer une vraie table de production.
Graham Griffiths
il suffit d'exécuter cette instruction 'drop table tabletwo;' et exécutez la requête ci-dessus. Sélectionnez ... dans n'est pas pour les tables temporaires.
Shiwangini

Réponses:

637

SELECT ... INTO ... ne fonctionne que si la table spécifiée dans la clause INTO n'existe pas - sinon, vous devez utiliser:

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

Cela suppose qu'il n'y a que deux colonnes dans dbo.TABLETWO - vous devez spécifier les colonnes sinon:

INSERT INTO dbo.TABLETWO
  (col1, col2)
SELECT col1, col2
  FROM dbo.TABLEONE
 WHERE col3 LIKE @search_key
Poneys OMG
la source
52
Il est recommandé de toujours spécifier les colonnes, qu'elles soient toutes présentes ou non. Cela aidera à empêcher les choses de se casser lorsque quelqu'un ajoute une colonne.
HLGEM
1
Hmm, l' SELECT... INTO...instruction ne semble pas fonctionner si la table spécifiée dans la INTOclause n'existe pas déjà. J'obtiens une erreur "variable non déclarée". Bien que ce problème ne concerne peut-être que MySQL. Le CREATE TABLE ... LIKE .. worked;
LazerSharks
1
@Gnuey SELECT ... INTO ... ne fonctionne que s'il existe une table existante. S'il n'y a pas de tableau existant, utilisez le format de l'affiche originale (qui créera un nouveau tableau)
Will
6
@ Will Voulez-vous dire le contraire de ce que vous avez dit? ´SELECT ... INTO ... ´ requiert la spécification d'une table non existante, tandis que ´INSERT INTO ... ´ nécessite la spécification d'une table existante.
André C. Andersen
5
Je souhaite qu'il y ait un compteur pour le nombre de fois que je reviens et utilise cette réponse!
MTAdmin
13

Il existe deux façons différentes d'implémenter l'insertion de données d'une table dans une autre table.

Pour une table existante - INSERT INTO SELECT

Cette méthode est utilisée lorsque la table est déjà créée dans la base de données plus tôt et que les données doivent être insérées dans cette table à partir d'une autre table. Si les colonnes répertoriées dans la clause insert et la clause select sont identiques, elles ne sont pas tenues de les répertorier. Il est recommandé de toujours les répertorier à des fins de lisibilité et d'évolutivité.

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

Pour les tables inexistantes - SELECT INTO

Cette méthode est utilisée lorsque la table n'est pas créée plus tôt et doit être créée lorsque des données d'une table doivent être insérées dans la table nouvellement créée à partir d'une autre table. La nouvelle table est créée avec les mêmes types de données que les colonnes sélectionnées.

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

Réf 1 2

Somnath Muluk
la source
3

Cela fonctionnerait comme indiqué ci-dessous:

insert into Gengl_Del Select Tdate,DocNo,Book,GlCode,OpGlcode,Amt,Narration 
from Gengl where BOOK='" & lblBook.Caption & "' AND DocNO=" & txtVno.Text & ""
Vinod Pareek
la source
5
+1 pour contrer le -1 et pour l'effort de donner des idées qui peuvent être utilisées ou référencées par d'autres utilisateurs. @MarkSowul a raison de l'injection SQL, mais pour des raisons académiques, d'autres personnes peuvent essayer ce type de méthode.
Albert Laure
1
La plupart des tables ont un champ d'incrémentation automatique, qui ne peut pas être inséré. Alors ça SELECT *ne marchera pas. C'est une meilleure façon, merci!
MJH du
2
@ User6675636b20796f7521 Je n'irais pas jusqu'à suggérer qu'il est "correct" pour d'autres personnes d'essayer ce genre de méthode, si c'est l'injection SQL dont nous parlons. Cela ne devrait jamais être fait, et donc ne devrait jamais être essayé. Il serait beaucoup plus productif de modifier cette réponse en montrant la bonne façon de le faire dès le début, et si quelqu'un demande, "qu'est-ce que les points d'interrogation / symboles?" vous répondez simplement «ce sont des marqueurs de paramètres à utiliser dans les requêtes paramétrées (hors de portée)» et laissez-les le comprendre à partir de là.
Matt Borja
2
select *
into existing table database..existingtable
from database..othertables....

Si vous avez select * into tablename from other tablenamesdéjà utilisé , la prochaine fois, pour ajouter, vous ditesselect * into existing table tablename from other tablenames

Verena_Techie
la source
2
PS Testé sur SYBASE ASE 15.5
Verena_Techie
10
L'OP demande MS SQL.
GrandMasterFlush
1

Si la table de destination existe mais que vous ne souhaitez pas spécifier de noms de 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
slayernoah
la source