2009-11-24 1 views
10

Вопрос SQL Server. При выполненииАвтоматически сопоставлять столбцы в INSERT INTO ... SELECT ... FROM

INSERT INTO T1 SELECT (C1, C2) FROM T2 

Я не хочу, чтобы указать имена столбцов T1, потому что они такие же, как и в T2

Можно ли сделать это?

В настоящее время я получаю ошибку

Msg 213, Level 16, State 1, Line 1

имя столбца или число предоставленных значений не соответствует определению таблицы.

ответ

2

Если T1 и T2 матч точно у вас есть два варианта. Вы можете либо select все столбцы от T2 для insert into T1, либо вы можете предоставить список столбцов в инструкции insert.

Несмотря на то, что когда вы делаете select, MSSQL предоставляет заголовки столбцов, которые не используются оператором insert для соответствия столбцам вверх.

1

Почему не просто

INSERT INTO t1 
SELECT * FROM T2 
+5

Мне нужно пропустить одну колонки (тот, который является идентичность первичного ключа) –

12

Да, вы можете опустить имена полей для таблицы, вставленной в, и вы можете использовать выберите *, чтобы получить все поля из таблицы, но я бы не стал рекомендуйте этот подход.

Если вы опускаете имя поля, поля соответствуют положению, а не по имени. Если поля не находятся в одном и том же порядке, они будут замешаны. Как правило, вам следует избегать использования точной компоновки таблиц, чтобы свести к минимуму риск того, что изменения в таблицах нарушают запросы.

+1

Есть ли способ, чтобы вставить все столбцы, кроме 'идентичности key' без указания всех имен столбцов?Таблицы, в которых я работаю, содержат десятки столбцов и перечисляют их каждый раз, это действительно скучно. –

+0

Возможно, вы могли бы создать представление со всеми нужными столбцами и выбрать * из него. – cindi

+1

@Konstantin: Нет, нет простого способа указать все поля, кроме поля идентификации. Это все или ничего. – Guffa

12

Всегда используйте явные столбцы как в INSERT, так и в проекции SELECT. Даже если вы не хотите, вы должны:

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

Это дублирование кода. Я хочу избавиться в пользу подхода, управляемого конвенциями (столбцы с одинаковыми именами должны просто сопоставляться друг с другом). –

+2

Копирование дублирования не должно быть хорошей практикой. –

+2

SQL, как правило, является подробным языком. Например, предложение group by является избыточным в агрегатах, INTO является избыточным. Думаю, вам просто нужно это принять. – cindi

0

Если вы беспокоитесь об именах столбцов вы можете всегда псевдоним них:

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

Или, более кратко:

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

Хотя я не могу по-настоящему думать, почему нужно было бы на таком простом примере

+0

Возможно ли иметь псевдоним для нескольких столбцов? Например, 'insert в T1 ALL_COLUMNS_ALIAS выберите (C1, C2, C3) как ALL_COLUMNS_ALIAS из T2'? –

-1

Он ссылается следующим образом:

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

Сначала выберите этот sql, выберите строку таблицы из результата sql и измените целевое или исходное имя-табло. Если таблицы имеют одинаковые столбцы (тот же порядок не нужен), это будет работа.

 
with xparams as (  select (select user from dual) "OWNER", '' "ADDSTRTOFROMTABLENAME" from dual ) 
    ,t1 as ( SELECT dbat.table_name from dba_tables dbat, xparams where dbat.owner = xparams.OWNER) 
    ,t1c1 as ( SELECT utcs.table_name , LISTAGG(utcs.column_name,',') within group (order by utcs.column_name) "COLS" from USER_TAB_COLUMNS utcs, t1 where utcs.table_name = t1.table_name group by utcs.table_name) 
    ,res1 as (SELECT 'insert into '|| t1c1.table_name || ' ('|| t1c1.COLS ||') select '|| t1c1.COLS || ' from ' || t1c1.table_name||xparams.ADDSTRTOFROMTABLENAME ||';' "RES" from t1c1, xparams order by t1c1.table_name) 
select * from res1