2016-11-30 82 views
0

我想要一個Oracle SQL查詢,它在運行時從一個特定的TABLE獲取所有COLUMN_NAMES,然後使用這些COLUMN_NAMES從每個ROW獲取值,因爲我不知道TABLE內COLUMNS的數量和名稱。Oracle查詢在運行時獲取所有COLUMN_NAMES,然後從每個行w.r.t中獲取值。每列

表1:

COLUMN_1, COLUMN_2, COLUMN_3, COLUMN_4 

value11 value12 value13 value14 

value21 value22 value23 value24 
... 

一個SQL查詢語句,我如下期望與各行對應的Insert語句的結果:

INSERT INTO TABLE1 VALUES (value11,value12,value13,value14); 

INSERT INTO TABLE1 VALUES (value21,value22,value23,value24); 

...

我的方法到目前爲止如下

查詢1

SELECT 'INSERT INTO TABLE1 VALUES (' ||COLUMN_1 ||',' ||COLUMN_2 ||',' ||COLUMN_3 ||',' ||COLUMN_4 ||');' AS INSERTSCRIPT FROM TABLE1 ORDER BY COLUMN_1;

使用此我得到所需的插入statments,但問題是「我想避免手動指定的列名的每個表(因爲有超過數百個這樣的表的更)」。

所以我一直在試圖接下來

QUERY 2

SELECT LISTAGG(COLUMN_NAME, ', ') WITHIN GROUP (ORDER BY COLUMN_ID) FROM USER_TAB_COLS WHERE TABLE_NAME = 'TABLE1';

其中列出了列作爲COLUMN_1, COLUMN_2, COLUMN_3, COLUMN_4但問題是,我不能夠使用此導致QUERY_1

在此先感謝!

回答

1
select 'select ' || LISTAGG(column_name , ',') within group (order by column_id) || ' from my_table' 
    from user_tab_columns 
    where table_name = 'MY_TABLE'; 

這樣的查詢會爲您產生查詢以選擇MY_TABLE中的所有列。

在PL/SQL你可以這樣做:

declare 
querysql varchar2; 
    select 'insert into my_table select ' || LISTAGG(column_name , ',') within group (order by column_id) || ' from my_table' into querysql 
    from user_tab_columns 
    where table_name = 'REFERENCE1'; 
    execute immediate querysql; 
end; 
0

我猜你需要DML發生器。類似的東西:

declare 
    v_table_name varchar2(30) := 'YOUR_TABLE'; 

    v_date_mask varchar2(64) := 'dd.mm.yyyy hh24:mi:ss'; 
    v_sql varchar2(4000); 

    cur int; 
    n int; 
    v_cols dbms_sql.desc_tab; 

    v_varchar2 varchar2(10); 
    v_number number; 
    v_date date; 

    v_column_list varchar2(4000); 
    v_values_list varchar2(4000); 
    v_single_value varchar2(4000); 
begin 
    v_sql := 'select * from ' || v_table_name; 

    cur := dbms_sql.open_cursor; 
    dbms_sql.parse(cur, v_sql, dbms_sql.native); 

    dbms_sql.describe_columns(c => cur, col_cnt => n, desc_t => v_cols); 

    for i in v_cols.first..v_cols.last 
    loop 
     case 
     when v_cols(i).col_type = dbms_sql.Varchar2_Type 
     then 
      dbms_sql.define_column_char(c => cur, position => i, column => v_varchar2 , column_size => v_cols(i).col_max_len); 
     when v_cols(i).col_type = dbms_sql.Number_Type 
     then 
      dbms_sql.define_column(c => cur, position => i, column => v_number); 
     when v_cols(i).col_type = dbms_sql.Date_Type 
     then 
      dbms_sql.define_column(c => cur, position => i, column => v_date); 
     end case; 

     v_column_list := v_column_list || ',' || v_cols(i).col_name; 
    end loop; 
    v_column_list := ltrim(v_column_list,',');  

    n := dbms_sql.execute(cur); 

    n := dbms_sql.fetch_rows(cur); 

    while (n > 0) 
    loop 
     for i in v_cols.first..v_cols.last 
     loop 
      case 
      when v_cols(i).col_type = dbms_sql.Varchar2_Type 
      then 
       dbms_sql.column_value_char(c => cur, position => i, value => v_varchar2); 
       v_single_value := case 
           when v_varchar2 is not null 
           then '''' || trim(v_varchar2) || '''' 
           else 'NULL' 
           end; 
      when v_cols(i).col_type = dbms_sql.Number_Type 
      then 
       dbms_sql.column_value(c => cur, position => i, value => v_number); 
       v_single_value := nvl(to_char(v_number), 'NULL'); 
      when v_cols(i).col_type = dbms_sql.Date_Type 
      then 
       dbms_sql.column_value(c => cur, position => i, value => v_date); 
       v_single_value := case 
           when v_date is not null 
           then 'to_date(''' || to_char(v_date, v_date_mask) || ''',''' || v_date_mask || ''')' 
           else 'NULL' 
           end; 
      end case; 
      v_values_list := v_values_list || ',' || v_single_value;  
     end loop; 
     v_values_list := ltrim(v_values_list,','); 

     dbms_output.put_line ('INSERT INTO ' || v_table_name || '(' || v_column_list || ')'); 
     dbms_output.put_line (' VALUES (' || v_values_list || ');' || chr(10)); 

     v_values_list := null; 

     n := dbms_sql.fetch_rows(cur); 
    end loop; 

    dbms_sql.close_cursor(cur); 
    exception 
    when others then 
     dbms_sql.close_cursor(cur); 
     raise; 
end;