Generating sql insert into for Oracle

create or replace FUNCTION fn_gen_inserts
(
  p_sql                        CLOB, 
  p_new_owner_name             VARCHAR2,
  p_new_table_name             VARCHAR2
)
RETURN CLOB
IS
  l_cur                        NUMBER;
  l_sql                        CLOB := p_sql;
  l_ret                        NUMBER;
  l_col_cnt                    NUMBER;
  l_rec_tab                    dbms_sql.desc_tab;

  l_separator                  CHAR(1) := '!';
  l_clob                       CLOB;
  l_clob_line                  CLOB;
  l_clob_ins                   CLOB;
  l_clob_all                   CLOB;
  l_line                       CLOB := '-----------------------------------';

  cons_date_frm                VARCHAR2(32) := 'DD.MM.YYYY HH24:MI:SS';
  cons_timestamp_frm           VARCHAR2(32) := 'DD.MM.YYYY HH24:MI:SSXFF';
  cons_timestamp_wtz_frm       VARCHAR2(32) := 'DD.MM.YYYY HH24:MI:SSXFF TZR';

  cons_varchar2_code           NUMBER := 1;
  cons_nvarchar2_code          NUMBER := 1;
  cons_number_code             NUMBER := 2;
  cons_float_code              NUMBER := 2;
  cons_long_code               NUMBER := 8;
  cons_date_code               NUMBER := 12;
  cons_binary_float_code       NUMBER := 100;
  cons_binary_double_code      NUMBER := 101;
  cons_timestamp_code          NUMBER := 180;
  cons_timestamp_wtz_code      NUMBER := 181;
  cons_timestamp_lwtz_code     NUMBER := 231;
  cons_interval_ytm_code       NUMBER := 182;
  cons_interval_dts_code       NUMBER := 183;
  cons_raw_code                NUMBER := 23;
  cons_long_raw_code           NUMBER := 24;
  cons_rowid_code              NUMBER := 11;
  cons_urowid_code             NUMBER := 208;
  cons_char_code               NUMBER := 96;
  cons_nchar_code              NUMBER := 96;
  cons_clob_code               NUMBER := 112;
  cons_nclob_code              NUMBER := 112;
  cons_blob_code               NUMBER := 113;
  cons_bfile_code              NUMBER := 114;
  cons_xmltype_code            NUMBER := 109;

  -------------------------------------
  -- Supported types
  -------------------------------------
  l_varchar2_col                VARCHAR2(32767); --1
  l_number_col                  NUMBER;          --2
  --l_long_col                    long;          --8 - not supported
  l_date_col                    DATE;            --12
  --l_raw_col                     raw(2000);     --23 - not supported
  l_rowid_col                   ROWID;           --69
  l_char_col                    CHAR(2000);      --96
  l_binary_float_col            BINARY_FLOAT;    --100
  l_binary_double_col           BINARY_DOUBLE;   --101
  l_clob_col                    CLOB;            --112
  l_timestamp_col               TIMESTAMP(9);    --180
  l_timestamp_wtz_col           TIMESTAMP(9) WITH TIME ZONE;    --181
  l_interval_ytm_col            INTERVAL YEAR(9) TO MONTH;      --182
  l_interval_dts_col            INTERVAL DAY(9) TO SECOND(2);   --183
  l_urowid_col                  UROWID;                         --208
  l_timestamp_wltz_col          TIMESTAMP WITH LOCAL TIME ZONE; --231
  l_xmltype_col                 XMLTYPE; --109
  --l_nchar_col                   nchar(2000); --96 the same as char
  --l_nclob_col                   nclob; --112 the same as clob
  --l_blob_col - not supported
  --l_bfile_col - not supported
  --l_long_raw_col - not supported

  PROCEDURE print_rec(rec IN dbms_sql.desc_rec) IS
  BEGIN
    l_clob_all := l_clob_all||chr(10)||
      'col_type            =    ' || rec.col_type||chr(10)||
      'col_maxlen          =    ' || rec.col_max_len||chr(10)||
      'col_name            =    ' || rec.col_name||chr(10)||
      'col_name_len        =    ' || rec.col_name_len||chr(10)||
      'col_schema_name     =    ' || rec.col_schema_name||chr(10)||
      'col_schema_name_len =    ' || rec.col_schema_name_len||chr(10)||
      'col_precision       =    ' || rec.col_precision||chr(10)||
      'col_scale           =    ' || rec.col_scale||chr(10)||
      'col_null_ok         =    ';

    IF (rec.col_null_ok) THEN
      l_clob_all := l_clob_all||'true'||chr(10);
    ELSE
      l_clob_all := l_clob_all||'false'||chr(10);
    END IF;
  END;  
BEGIN
  ---------------------------------------
  -- INSERT - header generation
  ---------------------------------------
  l_clob_all := 
  'declare'||chr(10)||
  '  type   t_clob is table of clob index by binary_integer;'||chr(10)||
  '  l_clob t_clob;'||chr(10)||
  '  type   t_varchar2 is table of varchar2(64) index by binary_integer;'||chr(10)||
  '  l_varchar2 t_varchar2;'||chr(10)||
  'begin'||chr(10)||
  '/*'||chr(10);

  ---------------------------------------
  -- Introduction
  ---------------------------------------
  l_clob_all := l_clob_all||l_line||chr(10)||'Parsing query:'||chr(10)||l_sql||chr(10);

  ---------------------------------------
  -- Open parse cursor
  ---------------------------------------
  l_cur := dbms_sql.open_cursor;
  dbms_sql.parse(l_cur, l_sql, dbms_sql.NATIVE);

  ---------------------------------------
  -- Describe columns
  ---------------------------------------
  l_clob_all := l_clob_all||l_line||chr(10)||'Describe columns:'||chr(10);

  dbms_sql.describe_columns(l_cur, l_col_cnt, l_rec_tab);

  FOR i IN 1..l_rec_tab.count
  loop
    print_rec(l_rec_tab(i));
  END loop;

  l_clob_all := l_clob_all||chr(10)||
            '*/'||chr(10)||
            '  '||chr(10)||l_line||chr(10)||
            '  -- start generation of records'||chr(10)||
            '  '||l_line||chr(10);

  ---------------------------------------
  -- Define columns
  ---------------------------------------
  FOR i IN 1..l_rec_tab.count
  loop
    IF    l_rec_tab(i).col_type = cons_varchar2_code THEN --varchar2
      dbms_sql.define_column(l_cur, i, l_varchar2_col, l_rec_tab(i).col_max_len); 
    elsif l_rec_tab(i).col_type = cons_number_code THEN --number
      dbms_sql.define_column(l_cur, i, l_number_col); 
    --elsif l_rec_tab(i).col_type = cons_long_code then --long
    --  dbms_sql.define_column_long(l_cur, i); 
    elsif l_rec_tab(i).col_type = cons_date_code THEN --date
      dbms_sql.define_column(l_cur, i, l_date_col); 
    elsif l_rec_tab(i).col_type = cons_binary_float_code THEN --binary_float
      dbms_sql.define_column(l_cur, i, l_binary_float_col); 
    elsif l_rec_tab(i).col_type = cons_binary_double_code THEN --binary_double
      dbms_sql.define_column(l_cur, i, l_binary_double_col); 
--    elsif l_rec_tab(i).col_type = cons_raw_code then --raw
--      dbms_sql.define_column_raw(l_cur, i, l_raw_col, l_rec_tab(i).col_max_len); 
    elsif l_rec_tab(i).col_type = cons_rowid_code THEN  --rowid
      dbms_sql.define_column_rowid(l_cur, i, l_rowid_col); 
    elsif l_rec_tab(i).col_type = cons_char_code THEN  --char
      dbms_sql.define_column_char(l_cur, i, l_char_col, l_rec_tab(i).col_max_len); 
    elsif l_rec_tab(i).col_type = cons_clob_code THEN --clob
      dbms_sql.define_column(l_cur, i, l_clob_col); 
    elsif l_rec_tab(i).col_type = cons_timestamp_code THEN --timestamp
      dbms_sql.define_column(l_cur, i, l_timestamp_col); 
    elsif l_rec_tab(i).col_type = cons_timestamp_wtz_code THEN --timestamp with time zone
      dbms_sql.define_column(l_cur, i, l_timestamp_wtz_col); 
    elsif l_rec_tab(i).col_type = cons_rowid_code THEN --urowid
      dbms_sql.define_column(l_cur, i, l_urowid_col); 
    elsif l_rec_tab(i).col_type = cons_timestamp_lwtz_code THEN --timestamp with local time zone
      dbms_sql.define_column(l_cur, i, l_timestamp_wltz_col); 
    elsif l_rec_tab(i).col_type = cons_interval_ytm_code THEN --interval year to month
      dbms_sql.define_column(l_cur, i, l_interval_ytm_col); 
    elsif l_rec_tab(i).col_type = cons_interval_dts_code THEN --interval day to second
      dbms_sql.define_column(l_cur, i, l_interval_dts_col); 
    elsif l_rec_tab(i).col_type = cons_urowid_code THEN --urowid
      dbms_sql.define_column(l_cur, i, l_urowid_col); 
    elsif l_rec_tab(i).col_type = cons_xmltype_code THEN --xmltype
      dbms_sql.define_column(l_cur, i, l_xmltype_col); 
    ELSE
      raise_application_error(-20001, 'Column: '||l_rec_tab(i).col_name||chr(10)||
                                      'Type not supported: '||l_rec_tab(i).col_type);
      --not supported
    END IF;
  END loop;

  ---------------------------------------
  -- Execute cursor
  ---------------------------------------
  l_ret := dbms_sql.EXECUTE(l_cur);

  ---------------------------------------
  -- Fetch rows
  ---------------------------------------
  loop
    l_ret := dbms_sql.fetch_rows(l_cur);
    exit WHEN l_ret = 0;

    ---------------------------------------
    -- Building INSERT - build column declarations
    ---------------------------------------
    l_clob_line := '';

    FOR i IN 1..l_rec_tab.count
    loop
      IF    l_rec_tab(i).col_type = cons_varchar2_code THEN --varchar2
        dbms_sql.COLUMN_VALUE(l_cur, i, l_varchar2_col); 
        l_clob := l_varchar2_col;
      elsif l_rec_tab(i).col_type = cons_number_code THEN --number
        dbms_sql.COLUMN_VALUE(l_cur, i, l_number_col); 
        l_clob := to_char(l_number_col);
--      elsif l_rec_tab(i).col_type = cons_long_code then --long
--        dbms_sql.column_value(l_cur, i, l_long_col); 
--        l_clob := l_long_col;
      elsif l_rec_tab(i).col_type = cons_date_code THEN --date
        dbms_sql.COLUMN_VALUE(l_cur, i, l_date_col); 
        l_clob := to_char(l_date_col, cons_date_frm);
      elsif l_rec_tab(i).col_type = cons_binary_float_code THEN --binary_float
        dbms_sql.COLUMN_VALUE(l_cur, i, l_binary_float_col); 
        l_clob := to_char(l_binary_float_col);
      elsif l_rec_tab(i).col_type = cons_binary_double_code THEN --binary_double
        dbms_sql.COLUMN_VALUE(l_cur, i, l_binary_double_col); 
        l_clob := to_char(l_binary_double_col);
--      elsif l_rec_tab(i).col_type = cons_raw_code then --raw
--        dbms_sql.column_value(l_cur, i, l_raw_col); 
--        l_clob := to_char(l_raw_col);
      elsif l_rec_tab(i).col_type = cons_rowid_code THEN --rowid
        dbms_sql.COLUMN_VALUE(l_cur, i, l_rowid_col); 
        l_clob := to_char(l_rowid_col);
      elsif l_rec_tab(i).col_type = cons_char_code THEN --char
        dbms_sql.column_value_char(l_cur, i, l_char_col); 
--      l_clob := substr(l_char_col, 1, l_rec_tab(i).col_max_len - 1);
        l_clob := substr(l_char_col, 1, l_rec_tab(i).col_max_len);
      elsif l_rec_tab(i).col_type = cons_clob_code THEN --clob
        dbms_sql.COLUMN_VALUE(l_cur, i, l_clob_col); 
        l_clob := l_clob_col;
      elsif l_rec_tab(i).col_type = cons_timestamp_code THEN --timestamp
        dbms_sql.COLUMN_VALUE(l_cur, i, l_timestamp_col); 
        l_clob := to_char(l_timestamp_col, cons_timestamp_frm);
      elsif l_rec_tab(i).col_type = cons_timestamp_wtz_code THEN --timestamp with time zone
        dbms_sql.COLUMN_VALUE(l_cur, i, l_timestamp_wtz_col); 
        l_clob := to_char(l_timestamp_wtz_col, cons_timestamp_wtz_frm);
      elsif l_rec_tab(i).col_type = cons_interval_ytm_code THEN --interval year to month
        dbms_sql.COLUMN_VALUE(l_cur, i, l_interval_ytm_col); 
        l_clob := to_char(l_interval_ytm_col);
      elsif l_rec_tab(i).col_type = cons_interval_dts_code THEN --interval day to second
        dbms_sql.COLUMN_VALUE(l_cur, i, l_interval_dts_col); 
        l_clob := to_char(l_interval_dts_col);
      elsif l_rec_tab(i).col_type = cons_urowid_code THEN --urowid
        dbms_sql.COLUMN_VALUE(l_cur, i, l_urowid_col); 
        l_clob := to_char(l_urowid_col);
      elsif l_rec_tab(i).col_type = cons_timestamp_lwtz_code THEN --timestamp with local time zone
        dbms_sql.COLUMN_VALUE(l_cur, i, l_timestamp_wltz_col); 
        l_clob := to_char(l_timestamp_wltz_col, cons_timestamp_wtz_frm);
      elsif l_rec_tab(i).col_type = cons_xmltype_code THEN --xmltype
        dbms_sql.COLUMN_VALUE(l_cur, i, l_xmltype_col); 
        l_clob := l_xmltype_col.getclobval();
      END IF;

      IF l_rec_tab(i).col_type IN (cons_clob_code, cons_char_code, cons_varchar2_code) THEN
        l_clob_line := l_clob_line||'  l_clob('||to_char(i)||') :=q'''||l_separator||l_clob||l_separator||''';'||chr(10);
      ELSIF l_rec_tab(i).col_type IN (cons_xmltype_code) THEN
        l_clob_line := l_clob_line||'  l_clob('||to_char(i)||') :=q'''||l_separator||l_clob||l_separator||''';'||chr(10);
      ELSE
        l_clob_line := l_clob_line||'  l_varchar2('||to_char(i)||') :=q'''||l_separator||l_clob||l_separator||''';'||chr(10);
      END IF;
    END loop;

    l_clob_all := l_clob_all||chr(10)||l_clob_line;

    ---------------------------------------
    -- Building INSERT - build column list
    ---------------------------------------
    l_clob_all := l_clob_all||chr(10)||
              '  insert into '||p_new_owner_name||'.'||p_new_table_name||chr(10)||
              '  ('||chr(10);

    FOR i IN 1..l_rec_tab.count
    loop
      IF i = 1 THEN
        l_clob_all := l_clob_all||'     '||l_rec_tab(i).col_name||chr(10);
      ELSE  
        l_clob_all := l_clob_all||'    ,'||l_rec_tab(i).col_name||chr(10);
      END IF;  
    END loop;    

    l_clob_all := l_clob_all||
              '  )'||chr(10)||
              '  values'||chr(10)||
              '  ('||chr(10);

    ---------------------------------------
    -- Building INSERT - build values
    ---------------------------------------
    FOR i IN 1..l_rec_tab.count
    loop
      IF i!=1 THEN
        l_clob_all := l_clob_all||'    ,';
      ELSE  
        l_clob_all := l_clob_all||'     ';
      END IF;

      IF l_rec_tab(i).col_type = cons_number_code THEN --number
        l_clob_all := l_clob_all||'to_number(l_varchar2('||to_char(i)||'))'||chr(10);
--      elsif l_rec_tab(i).col_type = cons_long_code then --long
--        l_clob := l_long_col;
      elsif l_rec_tab(i).col_type = cons_clob_code THEN --clob, xmltype
        l_clob_all := l_clob_all||'l_clob('||to_char(i)||')'||chr(10);
      ELSIF L_REC_TAB(I).COL_TYPE = CONS_XMLTYPE_CODE then --clob, xmltype
        l_clob_all := l_clob_all||'xmltype(l_clob('||to_char(i)||'))'||chr(10);
      elsif l_rec_tab(i).col_type = cons_char_code THEN --timestamp with local time zone
        l_clob_all := l_clob_all||'to_char(l_clob('||to_char(i)||'))'||chr(10);
      elsif l_rec_tab(i).col_type = cons_varchar2_code THEN --timestamp with local time zone
        l_clob_all := l_clob_all||'to_char(l_clob('||to_char(i)||'))'||chr(10);
      elsif l_rec_tab(i).col_type = cons_date_code THEN --date
        l_clob_all := l_clob_all||'to_date(l_varchar2('||to_char(i)||'),'''||cons_date_frm||''')'||chr(10);
      elsif l_rec_tab(i).col_type = cons_timestamp_code THEN --timestamp
        l_clob_all := l_clob_all||'to_timestamp(l_varchar2('||to_char(i)||'),'''||cons_timestamp_frm||''')'||chr(10);
      elsif l_rec_tab(i).col_type = cons_timestamp_wtz_code THEN --timestamp with time zone
        l_clob_all := l_clob_all||'to_timestamp_tz(l_varchar2('||to_char(i)||'),'''||cons_timestamp_wtz_frm||''')'||chr(10);
      elsif l_rec_tab(i).col_type = cons_interval_ytm_code THEN --interval year to month
        l_clob_all := l_clob_all||'to_yminterval(l_varchar2('||to_char(i)||'))'||chr(10);
      elsif l_rec_tab(i).col_type = cons_interval_dts_code THEN --interval day to second
        l_clob_all := l_clob_all||'to_dsinterval(l_varchar2('||to_char(i)||'))'||chr(10);
      elsif l_rec_tab(i).col_type = cons_timestamp_lwtz_code THEN --timestamp with local time zone
        l_clob_all := l_clob_all||'to_timestamp_tz(l_varchar2('||to_char(i)||'),'''||cons_timestamp_wtz_frm||''')'||chr(10);
      ELSE  
        l_clob_all := l_clob_all||'l_varchar2('||to_char(i)||')'||chr(10);
      END IF;  
    END loop; 

    l_clob_all := l_clob_all||'  );'||chr(10);
  END loop;

  ---------------------------------------
  -- Building INSERT - end of code
  ---------------------------------------
  l_clob_all := l_clob_all||chr(10)||'end;';
  l_clob_all := l_clob_all||chr(10)||'/';

  ---------------------------------------
  -- Close cursor
  ---------------------------------------
  dbms_sql.close_cursor(l_cur);

  RETURN l_clob_all;
END;
/
select fn_gen_inserts('select * from USG', 'UATDB', 'USG') from dual;

猜你喜欢

转载自www.cnblogs.com/kakaisgood/p/12228818.html
今日推荐