【问题标题】:Oracle query to gets all COLUMN_NAMES during run-time and then fetch value from each ROW w.r.t. each columnOracle 查询在运行时获取所有 COLUMN_NAMES,然后从每个 ROW w.r.t 获取值。每列
【发布时间】:2016-11-30 20:30:58
【问题描述】:

我想要一个 Oracle sql 查询,它在运行时从特定 TABLE 中获取所有 COLUMN_NAMES,然后使用这些 COLUMN_NAMES 从每个 ROW 中获取值,考虑到我不知道 TABLE 中 COLUMNS 的数量和名称。

表 1:

COLUMN_1, COLUMN_2, COLUMN_3, COLUMN_4

value11 value12 value13 value14

value21 value22 value23 value24
...

作为 sql 查询的结果,我期望插入语句对应于每一行,如下所示:

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;

使用它我得到了所需的插入语句,但问题是“我想避免为每个 TABLE 手动指定列名(因为有超过数百个这样的 TABLES)”。

所以我一直在尝试下一步

查询 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 中使用此结果

提前致谢!

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案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;
    

    【讨论】:

      【解决方案2】:

      我猜你需要 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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-18
        • 1970-01-01
        • 2014-02-21
        • 1970-01-01
        • 1970-01-01
        • 2021-11-28
        相关资源
        最近更新 更多