tags:

views:

148

answers:

1

I would like to do an INSERT / SELECT, this means INSERT in the TARGET_TABLE the records of the SOURCE_TABLE, with this assumption:

The SOURCE and the TARGET table have only a SUBSET of common columns, this means in example:

==> The SOURCE TABLE has ALPHA, BETA and GAMMA columns;
==> The TARGET TABLE has BETA, GAMMA and DELTA columns.

What is the most efficient way to produce INSERT / SELECT statements, respecting the assumption that not all the target columns are present in the source table?

The idea is that the PL/SQL script CHECKS the columns in the source table and in the target table, makes the INTERSECTION, and then produces a dynamic SQL with the correct list of columns.

Please assume that the columns present in the target table, but not present in the source table, have to be left NULL.

I wish to extract the data from SOURCE into a set of INSERT statements for later insertion into the TARGET table.

You can assume that the TARGET table has more columns than the SOURCE table, anche that all the columns in the SOURCE table are present in the TARGET table in the same order.

Thank you in advance for your useful suggestions!

+5  A: 

In Oracle, You can get common columns with this SQL query:

select column_name
  from user_tab_columns
 where table_name = 'TABLE_1'
intersect
select column_name
  from user_tab_columns
 where table_name = 'TABLE_2'

Then you iterate a cursor with the mentioned query to generate a comma separated list of all values returned. Put that comma separated string into a varchar2 variable named common_fields. Then, you can:

sql_sentence := 'insert into TABLE_1 (' || 
                 common_fields || 
                 ') select ' || 
                 common_fields ||
                 ' from TABLE_2';
execute immediate sql_sentence;
Pablo Santa Cruz
How can I modify this solution if SQL_SENTENCE has to contain the EXACT VALUES of the common_fields?
The chicken in the kitchen
What do you mean by **exact values**? I don't understand...
Pablo Santa Cruz
Please assume that COMMON_FIELDS can be DATE, NUMBER or VARCHAR2 datatype.
The chicken in the kitchen
SQL_SENTENCE := 'INSERT INTO TABLE_1 VALUES ('CUSTOM STRING', TO_DATE ('01/01/1980','DD/MM/YYYY'), -10, 123)';
The chicken in the kitchen
I would like to have in the SQL_SENTENCE the explicit values of the common fields, not their names.
The chicken in the kitchen
I see... You won't be able to do that in ONE sentence. You need multiple inserts to do that I guess...
Pablo Santa Cruz
Of course, multiple inserts for multiple records. These multiple inserts have to be executed with delay, so I store them in a table, for example. This is the reason why I need the REAL values, and not the columns' names.
The chicken in the kitchen
I see... Yes, you can use a similar approach. You will have to use a cursor to get the values, and then insert them one by one with another dynamic SQL sentence. Keep in mind though that this will be way slower (performance wise).
Pablo Santa Cruz
Could you help me for doing this?
The chicken in the kitchen
If you are on 11g you could use listagg (http://download.oracle.com/docs/cd/E14072_01/server.112/e10592/functions087.htm) to assemble the column names so you don't have to loop through them.
Leigh Riffel
No, I am using Oracle 10G R2
The chicken in the kitchen