前言:在表数据量特别大的时候,需要使用到dmfldr快速导入导出数据,如果表的数量特别多,手动创建费时费力,所以现在提供一个用存储过程创建的方式。
一、创建效果
1、先来看一下用存储过程创建了哪些东西。
2、下面是其中一个控制文件
3、执行命令
二、创建存储过程
1、在数据库实例目录下创建package文件夹和data文件夹
E:\dmdbms\data\DAMENG2\package 存放控制文件和脚本语句
E:\dmdbms\data\DAMENG2\data 存放导出的数据
注意:一定要在数据库实例下,不然会报权限不足。
2、存储过程语句解析
1)、UTL_FILE 包
UTL_FILE 包是PL/SQL 程序提供读和写操作系统数据文件的功能。
2)、使用包内的过程和函数之前,如果还未创建过系统包。请先调用系统过程创建系统包。
SP_CREATE_SYSTEM_PACKAGES (1,'UTL_FILE');
3)、UTL_FILE 定义了一种 FILE_TYPE 记录类型。FILE_TYPE 类型是 UTL_FILE 专有类型。
4)、utl_file.fopen
当用户想读取或写一个数据文件的时候,可以使用 FOPEN 来返回的文件句柄。这个文件句柄将用于随后在文件上的所有操作。
第一个参数是源文件路径,第二个参数是文件名称,第三个参数是文件打开模式,A代表附加模式,R代表只读模式,W代表写模式,当以"A"的方式打开文件时,若该文件不存在,则以"W"的方式创建该文件。
3、调用存储过程
call dmhr.DMFLDR_CTL_DATA('E:\dmdbms\data\DAMENG2\package\','DMHR','E:\dmdbms\data\DAMENG2\data\','SYSDBA','SYSDBA','LOCALHOST','5237');
三、导出
1、创建导出脚本exetable.bat,并把E:\dmdbms\data\DAMENG2\package\dmfldr.txt文件中的执行语句copy到执行脚本中。
2、执行脚本
在E:\dmdbms\bin目录下cmd
call E:\dmdbms\data\DAMENG2\package\exetable.bat
3、执行效果
四、导入
1、创建导入脚本exeintotable.bat,并把E:\dmdbms\data\DAMENG2\package\dmfldr.txt文件中的执行语句copy到执行脚本中,把mode='OUT'删除即可。或者直接复制黏贴导出脚本再删除mode='OUT'。
2、执行导入脚本
3、导入效果
原本只有11条记录,现在有22条记录。
五、最后附上存储过程创建语句
--参数说明
--FILE_PATH 生成的控制文件路径(为数据库实例位置,不然会报权限不足),生成的执行脚本中已指向该目录,无需移动
--V_SEC_NAME 导出模式名
--DATA_FILE 生成数据文件位置
--USER_NAME 用户名
--PASSWORD 密码
--变量说明
--l_file 对应的是控制文件,有几张表生成几个控制文件
--exec_file 只生成一个文件,存放执行命令,copy进执行脚本即可
create or replace procedure DMHR.DMFLDR_CTL_DATA(FILE_PATH STRING,v_SEC_NAME STRING,
DATA_FILE STRING,USER_NAME STRING,PASSWORD STRING,IP STRING,PORT STRING)
is
l_file utl_file.file_type;--控制文件,有几张表生成几个
exec_file utl_file.file_type;--存放执行命令,只生成一个文件,把该文件内容copy进执行脚本即可
i int;
begin
exec_file:=utl_file.fopen(FILE_PATH, 'dmfldr.txt', 'A');--存放执行命令的文件的名称为dmfldr.txt
--获取模式下所有的表并循环创建控制文件和执行脚本
for a in(select * from all_tables where OWNER=v_SEC_NAME) loop
l_file :=utl_file.fopen(FILE_PATH, a.TABLE_NAME||'.ctl', 'A');
utl_file.putf(exec_file, 'dmfldr.exe userid='|| USER_NAME||'/'||PASSWORD ||'@'||IP||':'||PORT||' control=');
utl_file.putf(exec_file, '''');
utl_FILE.putf(exec_file, FILE_PATH );
utl_file.putf(exec_file, a.TABLE_NAME||'.ctl''');
utl_file.putf(exec_file, ' ');
utl_file.putf(exec_file, 'mode='||'''OUT''');
UTL_FILE.putf(exec_file, '\n');
--utl_file_putf(exec_file,'\N');
utl_file.putf(l_file, 'LOAD DATA');
utl_file.putf(l_file, '\nINFILE');
utl_file.putf(l_file, ' ');
utl_file.putf(l_file, '''');
utl_file.putf(l_file, DATA_FILE);
utl_file.putf(l_file, a.TABLE_NAME||'.txt''');--数据文件名称
UTL_file.putf(L_file, '\nINTO TABLE');
utl_file.putf(l_file, ' ');
utl_file.putf(l_file, v_SEC_NAME||'.'||a.TABLE_NAME);
utl_file.putf(l_file, '\nFIELDS ''|''');
UTL_FILE.putf(l_file, '\n(');
i :=0;
--循环封装表下的列信息,新版本达梦数据库已支持简化方式,控制文件指定表即可,不用指定字段信息了,当然
for b in ( select * from all_tab_columns where owner = v_SEC_NAME and table_name=a.TABLE_NAME ) loop
utl_file.putf(l_file, b.COLUMN_NAME);
i :=i+1;
if i < (select count(*) from all_tab_columns where owner = V_SEC_NAME and table_name = a.TABLE_NAME )
then utl_file.putf(l_file, ',');
end if;
UTL_FILE.putf(l_file, '\n');
end loop;
UTL_FILE.putf(l_file, '\n)');
UTL_FILE.putf(l_file, '\n');
end loop;
utl_file.fclose(l_file);
utl_file.fclose(exec_file);
end;
--调用实例
call dmhr.DMFLDR_CTL_DATA('E:\dmdbms\data\DAMENG2\package\','DMHR','E:\dmdbms\data\DAMENG2\data\','SYSDBA','SYSDBA','LOCALHOST','5237');