I\'m using Oracle db and I wonder if it\'s possible to write something like:
INSERT INTO CL (select COLUMN_NAME from USER_TAB_COLUMNS where TABLE_NAME=\'CL\')
SE
No, you can't use a subquery to generate the column list as part of an SQL statement.
You can generate the full statement from the data dictionary:
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';
and then either copy and paste that, or use dynamic SQL from an anonymous block:
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;
/
With a couple of dummy tables:
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
running that block gives:
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
You could also turn that anonymous block into a procedure that takes two table names if this is something you're likely to want to do often (you said it needed to be reusable, but that could mean for the same tables, and could just be a block in a script).
You could also go further and only include columns that appear in both tables, or verify data types match exactly; though that's a bit more work and may well not be necessary.