[PL/SQL]使用存储过程实现导入指定文件的数据到数据库(针对本博客的EXP_DATA存储)(二)

2014-11-24 16:12:11 · 作者: · 浏览: 3
execute immediate v_sql; --先创建表
v_sql := 'INSERT INTO ' || v_user || '.' || V_TABLE || ' VALUES(';
else
v_filedstr := '';
FOR I IN 1 .. v_fileds.COUNT
LOOP
SELECT COUNT(*)
INTO I_TABLE
FROM ALL_tab_columns
WHERE TABLE_NAME = V_TABLE
AND OWNER = v_user
and COLUMN_NAME = UPPER(v_fileds(i));
if I_TABLE = 0 then
raise ex_table;
else
v_sql := v_sql || v_fileds(i) || ',';
select data_type
into v_filed
from ALL_tab_columns
where TABLE_NAME = V_TABLE
AND OWNER = v_user
and COLUMN_NAME = UPPER(v_fileds(i));
v_filedstr := v_filedstr || v_filed || ',';
end if;
end loop;
V_sql := substr(v_sql, 1, length(V_sql) - 1) || ') values('; --去掉最后的逗号
end if;
END IF;
if INSTR(v_text, ',') > 0 and INSTR(v_text, '[filed:]') = 0 then
select * bulk collect
into v_data
from table(splitstr(v_textTmp, v_sep));
select * bulk collect
into v_datatype
from table(splitstr(v_filedstr, ','));
V_esql := v_sql;
FOR I IN 1 .. v_data.COUNT
LOOP
CASE
WHEN INSTR(v_datatype(i), 'CHAR') > 0 THEN
if v_data(i) = 'null' then
V_esql := v_esql || 'NULL,';
else
V_esql := v_esql || ' ''' || v_data(i) || ''','; --处理数据类型
end if;
WHEN INSTR(v_datatype(i), 'NUMBER') > 0 THEN
if v_data(i) = 'null' then
V_esql := v_esql || 'NULL,';
else
V_esql := v_esql || ' ' || v_data(i) || ','; --处理数据类型
end if;
WHEN INSTR(v_datatype(i), 'DATE') > 0 THEN
if v_data(i) = 'null' then
V_esql := v_esql || 'NULL,';
else
IF length(v_data(i)) - length(replace(v_data(i), ':', '')) = 0 then
--日期数据格式确认
V_esql := v_esql || 'TO_DATE(''' || v_data(i) ||
''',''YYYY-MM-DD''),'; --处理数据类型
elsif length(v_data(i)) - length(replace(v_data(i), ':', '')) = 1 then
V_esql := v_esql || 'TO_DATE(''' || v_data(i) ||
''',''YYYY-MM-DD HH24:MI''),'; --处理数据类型
else
V_esql := v_esql || 'TO_DATE(''' || v_data(i) ||
''',''YYYY-MM-DD HH24:MI:SS''),'; --处理数据类型
end if;
end if;
END CASE;
end loop;
V_esql := substr(v_esql, 1, length(V_esql) - 1) || ')';
--dbms_output.put_line('v_sql:' || v_esql);
begin
execute immediate v_esql;
i_flag:=i_flag+1; --控制多少条记录提交一次
if i_flag=5000 then
commit;
i_flag:=0;
end if;
EXCEPTION
when others then
dbms_output.put_line('插入数据失败:[' || SQLCODE || '] ' || SQLERRM);
dbms_output.put_line('失败语句:' || v_esql);
end;
v_textTmp := '';
END IF;
end loop;
UTL_FILE.fclose(v_file);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line('导出数据成功完成!');
commit;
UTL_FILE.fclose(v_file);
when ex_table then
ROLLBACK;
raise_application_error(-20001,
'导入的表:' || V_TABLE || '已存在,且字段不一致!');