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条记录写一个文件,实现代码如下:

  1. create or replace procedure export_to_csv(P_DIR IN VARCHAR2)
  2. is
  3. CSV_OUTPUT UTL_FILE.FILE_TYPE;
  4. MAX_LINE NUMBER := 1000;
  5. OUT_FILE_NAME varchar2(20);
  6. OBJ_SIZE NUMBER;
  7. MIN_RECORD NUMBER;
  8. MAX_RECORD NUMBER;
  9. OBJ_DATE varchar2(100);
  10. BEGIN_TIME NUMBER;
  11. END_TIME NUMBER;
  12. begin
  13. BEGIN_TIME := dbms_utility.get_time; --记录开始时间,注意dbms_utility.get_time获取的时间戳单位是1/100s
  14. FOR I IN 0..999 loop
  15. OUT_FILE_NAME := 'output' || I || '.csv' ; --拼接文件名
  16. MIN_RECORD := i*1000 + 1; --分页查询起始记录
  17. MAX_RECORD := (i+1)*1000; --分页查询中止记录
  18. --以写方式打开指定目录中指定文件名文件
  19. CSV_OUTPUT := UTL_FILE.FOPEN(P_DIR, OUT_FILE_NAME, 'W' , MAX_LINE);
  20. --隐式游标,每次查询1000条记录
  21. FOR cur IN ( SELECT * FROM ( SELECT A.*, ROWNUM rn FROM ( SELECT * FROM aaa)A WHERE ROWNUM <= MAX_RECORD) WHERE rn >= MIN_RECORD) LOOP
  22. OBJ_SIZE := cur.OBJ_SIZE*10 + cur.MS_VERSION;
  23. --将数值类型数据转换为日期字符串
  24. OBJ_DATE := TO_CHAR(TO_DATE( '19700101' , 'yyyymmdd' ) + cur.OBJ_TIME/86400, 'yyyy-MM-dd HH24:mi' );
  25. --写文件
  26. UTL_FILE.PUT_LINE(CSV_OUTPUT,cur.OBJ_ID || '|' || cur.OBJ_NAME || ',' || OBJ_SIZE || ',' || OBJ_DATE || ',' || cur.OBJ_NAME);
  27. END LOOP;
  28. UTL_FILE.FCLOSE(CSV_OUTPUT);
  29. END LOOP;
  30. END_TIME := dbms_utility.get_time;
  31. DBMS_output.put_line( 'Total time=' || (END_TIME-BEGIN_TIME)*10 || 'ms.' );
  32. END ;
  33. /
  34. begin
  35. export_to_csv( 'MYDIR' );
  36. end ;
  37. /

经过 测试 ,1000个文件总共花150s,平均每个文件150ms。

注意:执行该存储过程之前,UTL_FILE的目录必须以sysdba的用户创建,然后授权给使用的用户,代码中的MYDIR通过下面方法创建:

首先,以sysdba用户登录。

其次,创建目录,如:CREATE DIRECTORY MYDIR AS 'c:\oraload\';

最后,给用户授权,如:GRANT READ,WRITE ON DIRECTORY MYDIR TO scott;

方案二:部分页,一次性将100万条记录全部查询出来放到游标中,每1000条写一个文件,代码如下:

  1. create or replace procedure export_to_csv(P_DIR IN VARCHAR2)
  2. is
  3. --显示游标,一次性将数据全部查询完
  4. cursor mycur is select * from aaa;
  5. --行记录
  6. myrecord aaa%rowtype;
  7. CSV_OUTPUT UTL_FILE.FILE_TYPE;
  8. MAX_LINE NUMBER := 1000;
  9. OUT_FILE_NAME varchar2(20);
  10. OBJ_SIZE NUMBER;
  11. OBJ_DATE varchar2(100);
  12. BEGIN_TIME NUMBER;
  13. END_TIME NUMBER;
  14. COUNT_NUM NUMBER;
  15. begin
  16. BEGIN_TIME := dbms_utility.get_time;
  17. --显式打开游标
  18. open mycur;
  19. FOR I IN 0..999 loop
  20. --拼接文件名
  21. OUT_FILE_NAME := 'output' || I || '.csv' ;
  22. COUNT_NUM := 0;
  23. --打开文件
  24. CSV_OUTPUT := UTL_FILE.FOPEN(P_DIR, OUT_FILE_NAME, 'W' , MAX_LINE);
  25. --每1000条写一个文件
  26. while COUNT_NUM < 1000 loop
  27. --逐条叫游标记录放入记录中
  28. fetch mycur into myrecord;
  29. OBJ_SIZE := myrecord.OBJ_SIZE*10 + myrecord.MS_VERSION;
  30. OBJ_DATE := TO_CHAR(TO_DATE( '19700101' , 'yyyymmdd' ) + myrecord.OBJ_TIME/86400, 'yyyy-MM-dd HH24:mi' );
  31. UTL_FILE.PUT_LINE(CSV_OUTPUT,myrecord.OBJ_ID || '|' || myrecord.OBJ_NAME || ',' || OBJ_SIZE || ',' || OBJ_DATE || ',' || myrecord.OBJ_NAME);
  32. COUNT_NUM := COUNT_NUM+1;
  33. --取游标中下一条记录
  34. fetch mycur into myrecord;
  35. END LOOP;
  36. UTL_FILE.FCLOSE(CSV_OUTPUT);
  37. END LOOP;
  38. --关闭游标
  39. close mycur;
  40. END_TIME := dbms_utility.get_time;
  41. DBMS_output.put_line( 'Total time=' || (END_TIME-BEGIN_TIME)*10 || 'ms.' );
  42. END ;
  43. /
  44. begin
  45. export_to_csv( 'MYDIR' );
  46. end ;
  47. /
经测试发现,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);