Faire correspondre automatiquement les colonnes dans INSERT INTO … SELECT … FROM

Question SQL Server En faisant

INSERT INTO T1 SELECT (C1, C2) FROM T2 

Je ne veux pas spécifier les noms de colonnes de T1 parce qu'ils sont les mêmes que dans T2

Est-il possible de le faire?

Actuellement, je reçois une erreur

Msg 213, niveau 16, état 1, ligne 1

Le nom de la colonne ou le nombre de valeurs fournies ne correspond pas à la définition de la table.

Si T1 et T2 correspondent exactement, vous avez deux choix. Vous pouvez select toutes les colonnes de T2 pour l' insert into T1 ou vous pouvez fournir une list de colonnes à l'instruction insert .

Même si vous faites une select MSSQL fournit des en-têtes de colonne cette information n'est pas utilisée par une instruction d' insert pour faire correspondre les colonnes.

Oui, vous pouvez omettre les noms des champs pour la table que vous insérez, et vous pouvez utiliser select * pour get tous les champs de la table, mais je ne reorderais pas cette approche.

Si vous omettez le nom du champ, les champs correspondent par position, pas par nom. Si les champs ne sont pas exactement dans le même ordre, ils seront mélangés. En général, vous devez éviter de vous fier à la disposition exacte des tables, afin de minimiser le risque que les modifications apscopes aux tables ne fassent obstacle aux requêtes.

Utilisez toujours des colonnes explicites à la fois dans l'INSERT et dans la projection SELECT. Même si vous ne le souhaitez pas, vous devriez:

 INSERT INTO T1 (C1, c2) SELECT C1, C2 FROM T2 

Pourquoi pas simplement

 INSERT INTO t1 SELECT * FROM T2 

Si vous êtes inquiet au sujet des noms de colonnes, vous pouvez toujours les alias:

 INSERT INTO T1 (C1, c2) SELECT C1 AS C1_ALIAS, C2 AS C2_ALIAS FROM T2 

Ou, plus succinctement:

 INSERT INTO T1 (C1, c2) SELECT C1 C1_ALIAS, C2 C2_ALIAS FROM T2 

Bien que je ne puisse pas vraiment penser pourquoi on voudrait dans un tel exemple simple

Sélectionnez d'abord ce sql, choisissez votre ligne de table à partir du résultat SQL et modifiez le nom de table cible ou source. Si les tables ont les mêmes colonnes (le même ordre n'est pas nécessaire) cela fonctionnera.

  avec xparams comme (select (select l'user à partir de deux) "PROPRIETAIRE", "" ADDSTRTOFROMTABLENAME "à partir de deux)
   , t1 as (SELECT dbat.table_name de dba_tables dbat, xparams où dbat.owner = xparams.OWNER)
   , t1c1 as (SELECT utcs.table_name, LISTAGG (utcs.column_name, ',') dans le groupe (ordre par utcs.column_name) "COLS" de USER_TAB_COLUMNS utcs, t1 où utcs.table_name = t1.table_name groupe par utcs.table_name)
   , res1 as (SELECT 'insert dans' || t1c1.table_name || '(' || t1c1.COLS || ') Sélectionnez' || t1c1.COLS || 'à partir de' || t1c1.nom_table || xparams.ADDSTRTOFROMTABLENAME || ';' "RES" de t1c1, command xparams par t1c1.table_name)
 select * de res1

Il est référencé comme suit:

 INSERT INTO NEWTABLENAME COL1[,COL2,..COLN] SELECT COL1[,COL2,..COLN] FROM THE EXISTINGTABLENAME