いいえ、サブクエリを使用してSQLステートメントの一部として列リストを生成することはできません。
データディクショナリから完全なステートメントを生成できます:
select 'insert into cl ("'
|| listagg(column_name, '","') within group (order by column_id)
|| '") select "'
|| listagg(column_name, '","') within group (order by column_id)
|| '" from clt'
from user_tab_columns where table_name = 'CLT';
次に、それをコピーして貼り付けるか、匿名ブロックから動的SQLを使用します。
declare
stmt varchar2(4000);
begin
select 'insert into cl ("'
|| listagg(column_name, '","') within group (order by column_id)
|| '") select "'
|| listagg(column_name, '","') within group (order by column_id)
|| '" from clt'
into stmt
from user_tab_columns where table_name = 'CLT';
dbms_output.put_line(stmt); -- to check and debug
execute immediate stmt;
end;
/
ダミーテーブルがいくつかあります:
create table clt (col1 number, col2 date, col3 varchar2(10));
create table cl (col3 varchar2(10), col1 number, col2 date);
insert into clt (col1, col2, col3) values (42, date '2018-07-12', 'Test');
insert into cl
select * from clt;
SQL Error: ORA-00932: inconsistent datatypes: expected NUMBER got DATE
そのブロックを実行すると、次のようになります。
insert into cl ("COL1","COL2","COL3") select "COL1","COL2","COL3" from clt
PL/SQL procedure successfully completed.
select * from cl;
COL3 COL1 COL2
---------- ---------- ----------
Test 42 2018-07-12
また、これが頻繁に実行する可能性が高い場合は、その匿名ブロックを2つのテーブル名を使用するプロシージャに変換することもできます(再利用可能である必要があると述べましたが、同じテーブルを意味する可能性があります。スクリプト内のブロック)。
さらに進んで、両方のテーブルに表示される列のみを含めるか、データ型が完全に一致することを確認することもできます。それはもう少し手間がかかり、必要ないかもしれませんが。