Oracle
 sql >> Database >  >> RDS >> Oracle

inserisci in... seleziona ... con sottoquery o senza ordine delle colonne

No, non puoi utilizzare una sottoquery per generare l'elenco di colonne come parte di un'istruzione SQL.

Puoi generare la dichiarazione completa dal dizionario dei dati:

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

e quindi copialo e incollalo oppure usa l'SQL dinamico da un blocco anonimo:

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

Con un paio di tavoli fittizi:

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

l'esecuzione di quel blocco dà:

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

Potresti anche trasformare quel blocco anonimo in una procedura che accetta due nomi di tabelle se questo è qualcosa che probabilmente vorrai fare spesso (hai detto che doveva essere riutilizzabile, ma ciò potrebbe significare per le stesse tabelle e potrebbe essere semplicemente un blocco in uno script).

Puoi anche andare oltre e includere solo le colonne che appaiono in entrambe le tabelle o verificare che i tipi di dati corrispondano esattamente; anche se è un po' più di lavoro e potrebbe non essere necessario.