批量生成sqlldr文件,高速卸载数据

SQL*Loader 是用于将外部数据进行批量高速加载的数据库的最高效工具,可用于将多种平面格式文件加载到Oracle数据库。SQL*Loader支持传统路径模式以及直接路径这两种加载模式。关于SQL*Loader的具体用法可以参考Oracle Utilities 手册或者SQL*Loader使用方法。那么如何以SQL*Loader能识别的方式高效的卸载数据呢? Tom大师为我们提供了一个近乎完美的解决方案,是基于exp/imp,Datapump方式迁移数据的有力补充。本文基于此给出描述,并通过批量的方式来卸载数据。

有关本文涉及到的参考链接:
    SQL*Loader使用方法 
    数据泵 EXPDP 导出工具的使用    数据泵IMPDP 导入工具的使用    PL/SQL-->UTL_FILE包的使用介绍

1、单表卸载数据

[sql] view plain copy

print?

  1. --首先查看你的数据库是否存在相应的dump目录,如果没有,则应先使用create or replace directory dir_name as ‘/yourpath‘创建
  2. [email protected]SZ> @dba_directories
  3. Owner      Directory Name                 Directory Path
  4. ---------- ------------------------------ -------------------------------------------------
  5. SYS        DB_DUMP_DIR                    /u02/database/SYBO2SZ/BNR/dump
  6. --下面是用匿名的pl/sql块来卸载单表数据
  7. DECLARE
  8. l_rows   NUMBER;
  9. BEGIN
  10. l_rows :=
  11. unloader.run (p_query        => ‘select * from scott.emp order by empno‘,    --->定义你的查询
  12. p_tname        => ‘emp‘,                                       --->定义放入控制文件的表名
  13. p_mode         => ‘replace‘,                                   --->定义装载到目标表时使用的方式
  14. p_dir          => ‘DB_DUMP_DIR‘,                               --->定义卸载数据存放目录
  15. p_filename     => ‘emp‘,                                       --->定义生成的文件名
  16. p_separator    => ‘,‘,                                         --->字段分隔符
  17. p_enclosure    => ‘"‘,                                         --->封装每个字段的符合
  18. p_terminator   => ‘~‘);                                        --->行终止符
  19. DBMS_OUTPUT.put_line (TO_CHAR (l_rows) || ‘ rows extracted to ascii file‘);
  20. END;
  21. /
  22. 14 rows extracted to ascii file
  23. PL/SQL procedure successfully completed.
  24. --查看刚刚卸载数据生成的文件
  25. [email protected]> ho ls -hltr /u02/database/SYBO2SZ/BNR/dump
  26. total 8.0K
  27. -rw-r--r-- 1 oracle oinstall  913 2014-01-14 15:04 emp.dat
  28. -rw-r--r-- 1 oracle oinstall  261 2014-01-14 15:04 emp.ctl
  29. --查看卸载文件的内容
  30. [email protected]> ho more /u02/database/SYBO2SZ/BNR/dump/emp.dat
  31. "7369","SMITH","CLERK","7902","17121980000000","800","","20"~
  32. "7499","ALLEN","SALESMAN","7698","20021981000000","1600","300","30"~
  33. "7521","WARD","SALESMAN","7698","22021981000000","1250","500","30"~
  34. "7566","JONES","MANAGER","7839","02041981000000","2975","","20"~
  35. "7654","MARTIN","SALESMAN","7698","28091981000000","1250","1400","30"~
  36. "7698","BLAKE","MANAGER","7839","01051981000000","2850","","30"~
  37. "7782","CLARK","MANAGER","7839","09061981000000","2650","","10"~
  38. "7788","SCOTT","ANALYST","7566","19041987000000","3000","","20"~
  39. "7839","KING","PRESIDENT","","17111981000000","5200","","10"~
  40. "7844","TURNER","SALESMAN","7698","08091981000000","1500","0","30"~
  41. "7876","ADAMS","CLERK","7788","23051987000000","1100","","20"~
  42. "7900","JAMES","CLERK","7698","03121981000000","950","","30"~
  43. "7902","FORD","ANALYST","7566","03121981000000","3000","","20"~
  44. "7934","MILLER","CLERK","7782","23011982000000","1500","","10"~
  45. --下面是生成的控制文件,有了数据文件和控制文件可以直接进行导入目标表
  46. [email protected]> ho more /u02/database/SYBO2SZ/BNR/dump/emp.ctl
  47. load data
  48. infile ‘emp.dat‘ "str x‘7E0A‘"
  49. into table emp
  50. replace
  51. fields terminated by X‘2c‘ enclosed by X‘22‘
  52. (
  53. EMPNO char(44 ),
  54. ENAME char(20 ),
  55. JOB char(18 ),
  56. MGR char(44 ),
  57. HIREDATE date ‘ddmmyyyyhh24miss‘ ,
  58. SAL char(44 ),
  59. COMM char(44 ),
  60. DEPTNO char(44 )
  61. )
  62. --下面我们先truncate表emp,然后尝试使用sqlldr来装载数据
  63. [email protected]> truncate table emp;
  64. Table truncated.
  65. --装载数据到emp
  66. [email protected]:/u02/database/SYBO2SZ/BNR/dump> sqlldr scott/tiger control=emp.ctl data=emp.dat direct=true
  67. SQL*Loader: Release 10.2.0.3.0 - Production on Tue Jan 14 15:45:39 2014
  68. Copyright (c) 1982, 2005, Oracle.  All rights reserved.
  69. Load completed - logical record count 14.

2、批量卸载数据

[sql] view plain copy

print?

  1. --使用下面的匿名pl/sql块可以实现批量卸载数据,此处不演示
  2. DECLARE
  3. l_rows   NUMBER;
  4. v_sql    VARCHAR2 (200);
  5. CURSOR cur_tab
  6. IS
  7. SELECT table_name FROM user_tables;-->这里定义需要卸载的表,可以单独指定一个表用于存放需要卸载的对象,此处直接查询数据字典
  8. BEGIN
  9. FOR tab_name IN cur_tab
  10. LOOP
  11. v_sql := ‘select * from ‘ || tab_name.table_name;
  12. l_rows :=
  13. unloader.run (p_query        => v_sql,
  14. p_tname        => tab_name.table_name,
  15. p_mode         => ‘replace‘,
  16. p_dir          => ‘DB_DUMP_DIR‘,
  17. p_filename     => tab_name.table_name,
  18. p_separator    => ‘,‘,
  19. p_enclosure    => ‘"‘,
  20. p_terminator   => ‘~‘);
  21. -- Author : Leshami
  22. -- Blog   : http://blog.csdn.net/leshami
  23. DBMS_OUTPUT.put_line (TO_CHAR (l_rows) || ‘ rows extracted to ascii file‘);
  24. END LOOP;
  25. END;
  26. /

3、卸载数据原始脚本

[sql] view plain copy

print?

  1. [email protected]:~/dba_scripts/custom/tom> more unloader_pkg.sql
  2. CREATE OR REPLACE PACKAGE unloader
  3. AUTHID CURRENT_USER
  4. AS
  5. /* Function run -- unloads data from any query into a file
  6. and creates a control file to reload that
  7. data into another table
  8. --注释信息给出了比较详细的描述
  9. p_query = SQL query to "unload". May be virtually any query.
  10. p_tname = Table to load into. Will be put into control file.
  11. p_mode = REPLACE|APPEND|TRUNCATE -- how to reload the data
  12. p_dir = directory we will write the ctl and dat file to.
  13. p_filename = name of file to write to. I will add .ctl and .dat
  14. to this name
  15. p_separator = field delimiter. I default this to a comma.
  16. p_enclosure = what each field will be wrapped in
  17. p_terminator = end of line character. We use this so we can unload
  18. and reload data with newlines in it. I default to
  19. "|\n" (a pipe and a newline together) and "|\r\n" on NT.
  20. You need only to override this if you believe your
  21. data will have that sequence in it. I ALWAYS add the
  22. OS "end of line" marker to this sequence, you should not
  23. */
  24. FUNCTION run (p_query        IN VARCHAR2,
  25. p_tname        IN VARCHAR2,
  26. p_mode         IN VARCHAR2 DEFAULT ‘REPLACE‘,
  27. p_dir          IN VARCHAR2,
  28. p_filename     IN VARCHAR2,
  29. p_separator    IN VARCHAR2 DEFAULT ‘,‘,
  30. p_enclosure    IN VARCHAR2 DEFAULT ‘"‘,
  31. p_terminator   IN VARCHAR2 DEFAULT ‘|‘)
  32. RETURN NUMBER;
  33. END;
  34. /
  35. CREATE OR REPLACE PACKAGE BODY unloader
  36. AS
  37. g_thecursor   INTEGER DEFAULT DBMS_SQL.open_cursor;
  38. g_desctbl     DBMS_SQL.desc_tab;
  39. g_nl          VARCHAR2 (2) DEFAULT CHR (10);
  40. FUNCTION to_hex (p_str IN VARCHAR2)
  41. RETURN VARCHAR2
  42. IS
  43. BEGIN
  44. RETURN TO_CHAR (ASCII (p_str), ‘fm0x‘);
  45. END;
  46. FUNCTION is_windows
  47. RETURN BOOLEAN
  48. IS
  49. l_cfiles   VARCHAR2 (4000);
  50. l_dummy    NUMBER;
  51. BEGIN
  52. IF (DBMS_UTILITY.get_parameter_value (‘control_files‘, l_dummy, l_cfiles) > 0)
  53. THEN
  54. RETURN INSTR (l_cfiles, ‘\‘) > 0;
  55. ELSE
  56. RETURN FALSE;
  57. END IF;
  58. END;
  59. PROCEDURE dump_ctl (p_dir          IN VARCHAR2,
  60. p_filename     IN VARCHAR2,
  61. p_tname        IN VARCHAR2,
  62. p_mode         IN VARCHAR2,
  63. p_separator    IN VARCHAR2,
  64. p_enclosure    IN VARCHAR2,
  65. p_terminator   IN VARCHAR2)
  66. IS
  67. l_output   UTL_FILE.file_type;
  68. l_sep      VARCHAR2 (5);
  69. l_str      VARCHAR2 (5) := CHR (10);
  70. BEGIN
  71. IF (is_windows)
  72. THEN
  73. l_str := CHR (13) || CHR (10);
  74. END IF;
  75. l_output := UTL_FILE.fopen (p_dir, p_filename || ‘.ctl‘, ‘w‘);
  76. UTL_FILE.put_line (l_output, ‘load data‘);
  77. UTL_FILE.put_line (l_output, ‘infile ‘‘‘ || p_filename || ‘.dat‘‘ "str x‘‘‘ || UTL_RAW.cast_to_raw (p_terminator || l_str) || ‘‘‘"‘);
  78. UTL_FILE.put_line (l_output, ‘into table ‘ || p_tname);
  79. UTL_FILE.put_line (l_output, p_mode);
  80. UTL_FILE.put_line (l_output, ‘fields terminated by X‘‘‘ || to_hex (p_separator) || ‘‘‘ enclosed by X‘‘‘ || to_hex (p_enclosure) || ‘‘‘ ‘);
  81. UTL_FILE.put_line (l_output, ‘(‘);
  82. FOR i IN 1 .. g_desctbl.COUNT
  83. LOOP
  84. IF (g_desctbl (i).col_type = 12)
  85. THEN
  86. UTL_FILE.put (l_output, l_sep || g_desctbl (i).col_name || ‘ date ‘‘ddmmyyyyhh24miss‘‘ ‘);
  87. ELSE
  88. UTL_FILE.put (l_output, l_sep || g_desctbl (i).col_name || ‘ char(‘ || TO_CHAR (g_desctbl (i).col_max_len * 2) || ‘ )‘);
  89. END IF;
  90. l_sep := ‘,‘ || g_nl;
  91. END LOOP;
  92. UTL_FILE.put_line (l_output, g_nl || ‘)‘);
  93. UTL_FILE.fclose (l_output);
  94. END;
  95. FUNCTION quote (p_str IN VARCHAR2, p_enclosure IN VARCHAR2)
  96. RETURN VARCHAR2
  97. IS
  98. BEGIN
  99. RETURN p_enclosure || REPLACE (p_str, p_enclosure, p_enclosure || p_enclosure) || p_enclosure;
  100. END;
  101. FUNCTION run (p_query        IN VARCHAR2,
  102. p_tname        IN VARCHAR2,
  103. p_mode         IN VARCHAR2 DEFAULT ‘REPLACE‘,
  104. p_dir          IN VARCHAR2,
  105. p_filename     IN VARCHAR2,
  106. p_separator    IN VARCHAR2 DEFAULT ‘,‘,
  107. p_enclosure    IN VARCHAR2 DEFAULT ‘"‘,
  108. p_terminator   IN VARCHAR2 DEFAULT ‘|‘)
  109. RETURN NUMBER
  110. IS
  111. l_output        UTL_FILE.file_type;
  112. l_columnvalue   VARCHAR2 (4000);
  113. l_colcnt        NUMBER DEFAULT 0;
  114. l_separator     VARCHAR2 (10) DEFAULT ‘‘;
  115. l_cnt           NUMBER DEFAULT 0;
  116. l_line          LONG;
  117. l_datefmt       VARCHAR2 (255);
  118. l_desctbl       DBMS_SQL.desc_tab;
  119. BEGIN
  120. SELECT VALUE
  121. INTO l_datefmt
  122. FROM nls_session_parameters
  123. WHERE parameter = ‘NLS_DATE_FORMAT‘;
  124. /*
  125. Set the date format to a big numeric string. Avoids
  126. all NLS issues and saves both the time and date.
  127. */
  128. EXECUTE IMMEDIATE ‘alter session set nls_date_format=‘‘ddmmyyyyhh24miss‘‘ ‘;
  129. /*
  130. Set up an exception block so that in the event of any
  131. error, we can at least reset the date format.
  132. */
  133. BEGIN
  134. /*
  135. Parse and describe the query. We reset the
  136. descTbl to an empty table so .count on it
  137. will be reliable.
  138. */
  139. DBMS_SQL.parse (g_thecursor, p_query, DBMS_SQL.native);
  140. g_desctbl := l_desctbl;
  141. DBMS_SQL.describe_columns (g_thecursor, l_colcnt, g_desctbl);
  142. /*
  143. Create a control file to reload this data
  144. into the desired table.
  145. */
  146. dump_ctl (p_dir,
  147. p_filename,
  148. p_tname,
  149. p_mode,
  150. p_separator,
  151. p_enclosure,
  152. p_terminator);
  153. /*
  154. Bind every single column to a varchar2(4000). We don‘t care
  155. if we are fetching a number or a date or whatever.
  156. Everything can be a string.
  157. */
  158. FOR i IN 1 .. l_colcnt
  159. LOOP
  160. DBMS_SQL.define_column (g_thecursor,
  161. i,
  162. l_columnvalue,
  163. 4000);
  164. END LOOP;
  165. /*
  166. Run the query - ignore the output of execute. It is only
  167. valid when the DML is an insert/update or delete.
  168. */
  169. l_cnt := DBMS_SQL.execute (g_thecursor);
  170. /*
  171. Open the file to write output to and then write the
  172. delimited data to it.
  173. */
  174. l_output :=
  175. UTL_FILE.fopen (p_dir,
  176. p_filename || ‘.dat‘,
  177. ‘w‘,
  178. 32760);
  179. LOOP
  180. EXIT WHEN (DBMS_SQL.fetch_rows (g_thecursor) <= 0);
  181. l_separator := ‘‘;
  182. l_line := NULL;
  183. FOR i IN 1 .. l_colcnt
  184. LOOP
  185. DBMS_SQL.COLUMN_VALUE (g_thecursor, i, l_columnvalue);
  186. l_line := l_line || l_separator || quote (l_columnvalue, p_enclosure);
  187. l_separator := p_separator;
  188. END LOOP;
  189. l_line := l_line || p_terminator;
  190. UTL_FILE.put_line (l_output, l_line);
  191. l_cnt := l_cnt + 1;
  192. END LOOP;
  193. UTL_FILE.fclose (l_output);
  194. /*
  195. Now reset the date format and return the number of rows
  196. written to the output file.
  197. */
  198. EXECUTE IMMEDIATE ‘alter session set nls_date_format=‘‘‘ || l_datefmt || ‘‘‘‘;
  199. RETURN l_cnt;
  200. EXCEPTION
  201. /*
  202. In the event of ANY error, reset the data format and
  203. re-raise the error.
  204. */
  205. WHEN OTHERS
  206. THEN
  207. EXECUTE IMMEDIATE ‘alter session set nls_date_format=‘‘‘ || l_datefmt || ‘‘‘‘;
  208. RAISE;
  209. END;
  210. END run;
  211. END unloader;
  212. /

4、小结
a、本文描述了单表以及多表如何高速卸载数据,并且批量生成sqlldr的控制文件及数据文件
b、包调用者应该对unloader其具有execute权限以及表上的select权限
c、包主要是通过utl_file来写出到控制文件和数据文件,有关utl_file用法可参考:PL/SQL-->UTL_FILE包的使用介绍 
d、Tom大师的这个包支持lob数据类型,但其字节不能大于4000,以及不支持long raw

转:http://blog.csdn.net/leshami/article/details/18266003

时间: 2024-12-20 01:18:24

批量生成sqlldr文件,高速卸载数据的相关文章

批量生成控制文件,用sqlldr自动导入多个表的数据

生成控制文件 准备工作: SQL>set colsep ' '; //-域输出分隔符SQL>set echo off; //显示start启动的脚本中的每个sql命令,缺省为onSQL> set echo on //设置运行命令是是否显示语句SQL> set feedback on; //设置显示"已选择XX行"SQL>set feedback off; //回显本次sql命令处理的记录条数,缺省为onSQL>set heading off; //输

轻量级ORM 利用T4模板 批量生成多文件 实体和业务逻辑 代码

FluentData,它是一个轻量级框架,关注性能和易用性. 下载地址:FlunenData.Model 利用T4模板,[MultipleOutputHelper.ttinclude]批量生成多文件 基本语法: 1. 初始化:获取MultipleOutputHelper.ttinclude文件模板 在T4模板导入 //导入MultipleOutputHelper.ttinclude文件 路径 <#@include file="$(SolutionDir)\ORM.Model\T4\Mult

sqlldr批量生成控制文件

参考文档:http://askjoey.blog.51cto.com/7594056/1671852 环境:oracle11g,redhat linux 1.建立基础表 create table TAB_COLUMN_UNION(  TAB_COLUMN_ORA    VARCHAR2(4000),  TAB_COLUMN_SOURCE VARCHAR2(4000),  TABLE_NAME        VARCHAR2(500))tablespace SDATA  pctfree 10  i

T4批量生成多文件

http://www.cnblogs.com/zengxiangzhan/p/3250105.html Manager.ttinclude <#@ assembly name="System.Core"#> <#@ assembly name="System.Data.Linq"#> <#@ assembly name="EnvDTE"#> <#@ assembly name="System.X

asp.net asp.net application 升级到 asp.net web 解决找不到控件 批量生成.designer文件

颇费周折后,其实很简单,只需要生成designer文件后,重新保存所有页面即可.就是懒得写.懒真的是一种病,手上不能懒,脑子里更不能懒,否则就是给自己挖坑,仔细认真,注意细节!!!! PS:注意修改path变量为自己需要生成的web项目路径 需要注意的是,CodeBehind的路径是绝对路径 参考链接https://oomake.com/question/4935 对于VS2015 ...这里有一个用于从WebSite项目切换到适用于我的Web应用程序项目的VB示例.没有其他解决方案为我工作,这

利用Resgen.exe 批量生成resources文件

Resgen.exe(资源文件生成器)  您可以直接如图操作 转换时在 文本中先写好要转换的文件然后 全选 复制到控制台中 Filename.resx 要转换的文件 ResName1.resources 生成的resources 文件名 resgen E:\Filename1.resx e:\ResName1.resources resgen E:\Filename2.resx e:\ResName2.resources resgen E:\Filename3.resx e:\ResName3.

AFS Tool Excel 宏编写的工具 批量生成Excel 文件

AFS Tool Excel 宏编写的工具,文章最后附上工具下载. 主要实现的功能是在Excel中通过宏的编写, 按照一个模板,把大量的数据分类并生成多个Excel文件 AFS Tool中一共有3个Sheet: Info.Data.Cover Sheet: Info 中主要是用户操作界面及软件说明,只有一个生成文件的按钮, 点击的时候,会提示保存生成文件的路径,文件名按一定的格式生成. Sheet: Data中主要是存储要处理的数据 Sheet: Cover中主要是生成文件的模板,生成的Exce

shell脚本批量生成配置文件

如果管理的站点和服务器较多的情况下,每次修改配置文件都相当痛苦.因而想到了用shell脚本来批量生成配置文件和配置数据.下面这个脚本是为了批量生成nagios监控配置文件的一个shell脚本程序.其原理是事先定义一个shell脚本模板,然后每个需要监控的站点复制一份模板替换掉模板文件里面的变量. 1.准备模板文件webcheck.template more webcheck.template ###################WEBURL define start##############

中琅条码打印软件中如何批量生成条码

在使用中琅领跑条码打印软件制作商品标签过程中,经常需要大批量的根据我们的条码数据,批量生成条形码.一般来说这些数据是根据中国物品编码中心下发的厂商识别代码,加上商品标签申请单位商品的一些信息数字组合而成,为了方便管理和使用,一般存为excel,txt等文档.借助中琅领跑条码标签打印软件,我们可以通过导入数据源的方式批量生成条形码,那么具体如何操作呢,这里就以txt形式的文档为例,和大家分享一下在中琅条码打印软件中如何批量的生成条码.首先打开中琅领跑条码打印软件,新建一个标签纸张,因为是基本操作分