obj_size NUMBER NOT NULL
obj_time NUMBER NOT NULL
ms_version NUMBER NOT NULL
现在有100万条记录,要求每1000条记录导出为一个csv文件,共计1000个文件,文件名称格式为output0.csv,output1.csv......output999.csv。
每个csv文件每行记录包含:$1, $2, $3, $4四部分内容。
$1 = obj_id|obj_name
$2 = obj_size *10+obj_version
$3 = obj_time in format YYYY-MM-DD HH:mi
$4 = obj_name
要求第一个文件在500ms以内产生出来,后面每个文件生成间隔时间不得大于500ms,速度均匀。
方案一:使用pl/sql存储过程分页查询,每次查询1000条记录写一个文件,实现代码如下:
-
create
or
replace
procedure
export_to_csv(P_DIR
IN
VARCHAR2)
-
is
-
CSV_OUTPUT UTL_FILE.FILE_TYPE;
-
MAX_LINE NUMBER := 1000;
-
OUT_FILE_NAME varchar2(20);
-
OBJ_SIZE NUMBER;
-
MIN_RECORD NUMBER;
-
MAX_RECORD NUMBER;
-
OBJ_DATE varchar2(100);
-
BEGIN_TIME NUMBER;
-
END_TIME NUMBER;
-
begin
-
BEGIN_TIME := dbms_utility.get_time;
-
FOR
I
IN
0..999 loop
-
OUT_FILE_NAME :=
'output'
|| I ||
'.csv'
;
-
MIN_RECORD := i*1000 + 1;
-
MAX_RECORD := (i+1)*1000;
-
-
CSV_OUTPUT := UTL_FILE.FOPEN(P_DIR, OUT_FILE_NAME,
'W'
, MAX_LINE);
-
-
FOR
cur
IN
(
SELECT
*
FROM
(
SELECT
A.*, ROWNUM rn
FROM
(
SELECT
*
FROM
aaa)A
WHERE
ROWNUM <= MAX_RECORD)
WHERE
rn >= MIN_RECORD) LOOP
-
OBJ_SIZE := cur.OBJ_SIZE*10 + cur.MS_VERSION;
-
-
OBJ_DATE := TO_CHAR(TO_DATE(
'19700101'
,
'yyyymmdd'
) + cur.OBJ_TIME/86400,
'yyyy-MM-dd HH24:mi'
);
-
-
UTL_FILE.PUT_LINE(CSV_OUTPUT,cur.OBJ_ID ||
'|'
|| cur.OBJ_NAME ||
','
|| OBJ_SIZE ||
','
|| OBJ_DATE ||
','
|| cur.OBJ_NAME);
-
END
LOOP;
-
UTL_FILE.FCLOSE(CSV_OUTPUT);
-
END
LOOP;
-
END_TIME := dbms_utility.get_time;
-
DBMS_output.put_line(
'Total time='
|| (END_TIME-BEGIN_TIME)*10 ||
'ms.'
);
-
END
;
-
/
-
begin
-
export_to_csv(
'MYDIR'
);
-
end
;
-
/
经过
测试
,1000个文件总共花150s,平均每个文件150ms。
注意:执行该存储过程之前,UTL_FILE的目录必须以sysdba的用户创建,然后授权给使用的用户,代码中的MYDIR通过下面方法创建:
首先,以sysdba用户登录。
其次,创建目录,如:CREATE DIRECTORY MYDIR AS 'c:\oraload\';
最后,给用户授权,如:GRANT READ,WRITE ON DIRECTORY MYDIR TO scott;
方案二:部分页,一次性将100万条记录全部查询出来放到游标中,每1000条写一个文件,代码如下:
-
create
or
replace
procedure
export_to_csv(P_DIR
IN
VARCHAR2)
-
is
-
-
cursor
mycur
is
select
*
from
aaa;
-
-
myrecord aaa%rowtype;
-
CSV_OUTPUT UTL_FILE.FILE_TYPE;
-
MAX_LINE NUMBER := 1000;
-
OUT_FILE_NAME varchar2(20);
-
OBJ_SIZE NUMBER;
-
OBJ_DATE varchar2(100);
-
BEGIN_TIME NUMBER;
-
END_TIME NUMBER;
-
COUNT_NUM NUMBER;
-
begin
-
BEGIN_TIME := dbms_utility.get_time;
-
-
open
mycur;
-
FOR
I
IN
0..999 loop
-
-
OUT_FILE_NAME :=
'output'
|| I ||
'.csv'
;
-
COUNT_NUM := 0;
-
-
CSV_OUTPUT := UTL_FILE.FOPEN(P_DIR, OUT_FILE_NAME,
'W'
, MAX_LINE);
-
-
while COUNT_NUM < 1000 loop
-
-
fetch
mycur
into
myrecord;
-
OBJ_SIZE := myrecord.OBJ_SIZE*10 + myrecord.MS_VERSION;
-
OBJ_DATE := TO_CHAR(TO_DATE(
'19700101'
,
'yyyymmdd'
) + myrecord.OBJ_TIME/86400,
'yyyy-MM-dd HH24:mi'
);
-
UTL_FILE.PUT_LINE(CSV_OUTPUT,myrecord.OBJ_ID ||
'|'
|| myrecord.OBJ_NAME ||
','
|| OBJ_SIZE ||
','
|| OBJ_DATE ||
','
|| myrecord.OBJ_NAME);
-
COUNT_NUM := COUNT_NUM+1;
-
-
fetch
mycur
into
myrecord;
-
END
LOOP;
-
UTL_FILE.FCLOSE(CSV_OUTPUT);
-
END
LOOP;
-
-
close
mycur;
-
END_TIME := dbms_utility.get_time;
-
DBMS_output.put_line(
'Total time='
|| (END_TIME-BEGIN_TIME)*10 ||
'ms.'
);
-
END
;
-
/
-
begin
-
export_to_csv(
'MYDIR'
);
-
end
;
-
/
经测试发现,100万条记录总共耗时50s,平均每个文件50ms,速度大大提高。
数据库有如下表结构:aaa ( obj_id NUMBER, (Primary Key) obj_name VARCHAR2(80), obj_size NUMBER NOT NULL obj_time NUMBER NOT NULL
导出
oracle
表为
csv
小工具(
oracle
2
csv
_64.exe)
一、
oracle
2
csv
_64.ini中
1、可自定义单字符分隔符:SEPARATOR
2、USERNAME,PASSWORD可为空,运行时提示输入
二、支持带参数运行,便于用批处理语句
导出
多个
表
1、 -t 表名 (例:-t opera.customers@link_manage)
2、 -w 条件名(例:-w "ages>18 and name='jack'")
三、日志
文件
为:
oracle
2
csv
_64.log
四、需安装
oracle
客户端64位版本
本文实例讲述了Python
使用
cx_
Oracle
模块将
oracle
中
数据
导出
到
csv
文件
的方法。分享给大家供大家参考。具体实现方法如下:
# Export
Oracle
database tables to
CSV
files
# FB36 - 201007117
import sys
import
csv
import cx_
Oracle
connection = raw_input(Enter
Oracle
DB connection (uid/pwd@database) : )
orcl = cx_
Oracle
.connect(connection)
curs = orcl.cur
优点:高效;支持功能较多;用户只需有对应表查询权限;可以在从库执行
缺点:目前已没有再维护,只能找到基于
oracle
10.2的版本(高版本目前还可以用);密码必须要跟在用户名后面输,安全性不足
2. 下载安装
百度云链接:https://pan.baidu.com.
我通过这个方法,按照字段筛选
数据
,并分别
导出
多个
csv
文件
:
(1)首先创建存储一个过程,如下,直接复制粘贴即可 。这个
存储过程
可以直接
使用
,因为它是通用的,只需要你传入SQL和生成
文件
的路径就可以。
如果你想多了解一下的话,可以搜一搜
oracle
内置utl_file读写
文件
包 ,每分钟大约处理百万行。适用于
大量
导出
的情况
CREATE OR REPLAC...
最近课题组在和某航务管理局合作完成一个模拟仿真项目,对方发来某地一年的AIS
数据
,以DMP格式呈现,大小足有100多G。对于这批
数据
的处理首先需将其还原至
数据
库中,并以
CSV
文件
格式
导出
,此项任务最终分配给了笔者。在笔者着手完成的过程中,几天几夜,着实踩过不少坑。因此在此记录全过程以方便后来者。
众所周知,DMP
文件
(.dmp)通常来源于
Oracle
数据
库,属于一种备份
文件
存储格式。询问合作方了解到这批
数据
产自
Oracle
11g,对此笔者也是第一次接触。故而只得是走一步踩一步的坑...
需求:要往
数据
库表里造一批
数据
,用于测试人员测试,测试人员通过修改开始时间和结束时间来模拟这段时间的
数据
(
数据
时间间隔也作为参数配置)。
约束:1、
使用
存储过程
的方式。2、表名称也要作为一个参数传入。3、以下测试可能不太符合真实业务,仅仅是为了展示:表名做参数 if条件,for循环的用法。
环境:
数据
库:
Oracle
11g 可视化工具:PL/SQL
步骤1:
数据
库中有这样一张表(如图)记录了一个人每隔一段时间的身高变化(假设这个人一直长高)。
步骤2:想模拟一段时间的测试
数据
,开始...
客户又得出新的要求,想把某表中的某字段下面的所有
数据
导出
,嗯,大概有40多W条吧。。。
为了速度,还是利用
Oracle
自带的工具来处理,利用Spool来缓冲,关于Spool的参数定义大家自己网上查吧。
在D盘根目录(任意目录也可)建立一个名为export.sql的
文件
set feedback off heading off verify off trimspool on
create or replace directory DIR_EXCEL as '/opt/leasing';
create or replace procedure PRC_TASK_EXCEL is
out_file utl_file.file_type; --定义一个
文件
类型
L_FILENAME varchar2(200);