日期:2014-05-16  浏览次数:20478 次

oracle导出表insert语句存储过程

?

?

create or replace procedure print_insert(v_tname  varchar2,
                                         v_cbatch number default 0)
/*
  v_tname 要输出sql的表名
  v_cbatch 输出commit间隔
  */
 as
  /* 声明动态游标变量 */
  type cur_alldata is ref cursor;
  l_alldata cur_alldata;
  /* 将单行数据写入v_row*/
  v_sql varchar2(3999);
  v_row varchar2(3999);
  /* 函数的前向声明 */
  function formatfield(v_tname varchar2, v_cname varchar2, v_colno number)
    return varchar2;

  /* 格式化数据输出 */
  function formatdata(v_tname varchar2, v_row varchar2) return varchar2 as
    v_ldata varchar2(32765);
    v_rdata varchar2(32765);
    v_cname varchar2(3999);
    v_instr number(10);
    v_count number(6);
  begin
    v_instr := instr(v_row, '(', 1, 2); --INSTR(源字符串, 目标字符串, 起始位置, 匹配序号)
    v_ldata := substr(v_row, 1, v_instr);
    v_rdata := substr(v_row, v_instr + 1);
    v_instr := instr(v_rdata, ')', -1, 1);
    v_rdata := substr(v_rdata, 1, v_instr - 1);
  
    v_count := 0;
    loop
      v_instr := instr(v_rdata, ',');
      exit when v_instr = 0;
    
      v_cname := substr(v_rdata, 1, v_instr - 1);
      v_rdata := substr(v_rdata, v_instr + 1);
      v_count := v_count + 1;
      /* 格式化不同的数据类型 */
      v_cname := formatfield(v_tname, v_cname, v_count);
    
      /* 将处理后的字段值加入v_ldata */
      if v_count = 1 then
        v_ldata := v_ldata || v_cname;
      else
        v_ldata := v_ldata || ',' || v_cname;
      end if;
    
    end loop;
  
    /* 添加最后一个字段的值 */
    if v_count = 1 then
      v_ldata := v_ldata || formatfield(v_tname, v_rdata, v_count + 1) || ');';
    else
      v_ldata := v_ldata || ',' ||
                 formatfield(v_tname, v_rdata, v_count + 1) || ');';
    end if;
    dbms_output.put_line(v_ldata);
    return v_ldata;
  end;

  /* 针对不同的数据类型进行处理 */
  function formatfield(v_tname varchar2, v_cname varchar2, v_colno number)
    return varchar2 as
    v_name varchar2(3999);
    v_type varchar2(99);
  begin
    select coltype
      into v_type
      from col
     where tname = upper(v_tname)
       and colno = v_colno;
    --判断数据类型
    if v_type = 'DATE' then
      v_name := 'to_date(' || '''' || v_cname || '''' || ',' || '''' ||
                'yyyy-mm-dd hh24:mi:ss' || '''' || ')';
    elsif v_type = 'VARCHAR2' then
      v_name := '''' || v_cname || '''';
    elsif v_type = 'CHAR' then
      v_name := '''' || v_cname || '''';
    else
      v_name := v_cname;
    end if;
    return v_name;
  end;

  /* 求输入表的字段列表 */
  function getfields(v_tname varchar2) return varchar2 as
    v_fields    varchar2(3999);
    v_fieldName varchar2(3999);
  begin
    for cur_fname in (select cname, coltype
                        from col
                       where tname = upper(v_tname)
                       order by colno) loop
      if v_fields is null then
        v_fields := 'nvl(' || cur_fname.cname || ',' || '''' || '0' || '''' || ')';
      else
        v_fields := v_fields || '||'',''||' || 'nvl(' || cur_fname.cname || ',' || '''' || '0' || '''' || ')';
      end if;
      if v_fieldName is null then
        v_fieldName := cur_fname.cname;
      else
        v_fieldName := v_fieldName || ',' || cur_fname.cname;
      end if;
    end loop;
  
    v_fields := 'select ' || '''' || 'insert into ' || v_tname || ' (' ||
                v_fieldName || ') values(' || '''' || '||' || v_fields || '||' || '''' || ')' || '''' ||
                ' from ' || v_tname;
    return v_fields;
  end;
begin
  DBMS_OUTPUT.ENABLE(buffer_size => null); --解决PLSQL Developer 出现ORU-10027: buffer overflow, limit of 10000 bytes
  execute immediate 'alter session set nls_date_format=' || '''' ||
                    'yyyy-mm-dd hh24:mi:ss' || '''';
  dbms_output.put_line(' *** 表SQL输出 *** ');

  v_sql := getfields(v_tname);
  --dbms_output.put_line(v_sql);
  open l_alldata for v_sql;
  loop
    fetch l_alldata
      into v_row;
    exit when l_alldata%notfound;
    --dbms_output.put_line(v_row);
  
    dbms_ou