将任意表数据导出为CSV文件的过程

 

开发人员要实现一个自动将表中数据导出到一个csv格式文件的功能。建议他们使用UTL_FILE包加DBMS_JOB实现。最后给他们写了一个简单的UTL_FILE包使用的例子。


以前需要使用UTL_FILE包,必须设置utl_file_dir初始化参数,必须重启数据库才能使这个初始化参数修改生效。这成为使用UTL_FILE包最不方便的地方。

Oracle9i中,增强了UTL_FILE包的功能,使得UTL_FILE包可以使用DIRECTORY,这就解决了重启数据库的问题。

注意,由于对目录的读写具有比较大的安全隐患,因此CREATE DIRECTORY权限只授权给DBA用户,而且创建了DIRECTORY后,对DIRECTORY的读写操作的权限也要DBA来授权。

本例中,当前用户拥有DBA角色,因此省略了GRANT READ, WRITE ON DIRECTORY的步骤。

SQL> CREATE DIRECTORY D_OUTPUT AS 'E:';

目录已创建。

SQL> CREATE OR REPLACE PROCEDURE P_WRITE_EMP AS
2 V_FILE UTL_FILE.FILE_TYPE;
3 V_BUFFER VARCHAR2(32767);
4 BEGIN
5 V_FILE := UTL_FILE.FOPEN('D_OUTPUT', 'EMP' || TO_CHAR(SYSDATE, 'YYYY_MM_DD') || '.csv', 'w', 32767);
6 V_BUFFER := 'EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO';
7 UTL_FILE.PUT_LINE(V_FILE, V_BUFFER);
8 FOR I IN 
9 (
10 SELECT '"' || EMPNO || '","' || 
11 ENAME || '","' || 
12 JOB || '","' || 
13 MGR || '","' || 
14 HIREDATE || '","' || 
15 SAL || '","' || 
16 COMM || '","' || 
17 DEPTNO || '"' RESULT
18 FROM EMP
19 ) LOOP
20 UTL_FILE.PUT_LINE(V_FILE, I.RESULT);
21 END LOOP;
22 UTL_FILE.FCLOSE(V_FILE);
23 END;
24 /

过程已创建。

SQL> EXEC P_WRITE_EMP

PL/SQL 过程已成功完成。

例子很简单,这里就不多做解释了,最后给出文件EMP2006_09_06.csv的内容:

EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO
"7369","SMITH","CLERK","7902","1980-12-17 00:00:00","960","","20"
"7499","ALLEN","SALESMAN","7698","1981-02-20 00:00:00","1920","300","30"
"7521","WARD","SALESMAN","7698","1981-02-22 00:00:00","1500","500","30"
"7566","JONES","MANAGER","7839","1981-04-02 00:00:00","3570","","20"
"7654","MARTIN","SALESMAN","7698","1981-09-28 00:00:00","1500","1400","30"
"7698","BLAKE","MANAGER","7839","1981-05-01 00:00:00","3420","","30"
"7782","CLARK","MANAGER","7839","1981-06-09 00:00:00","2940","","10"
"7788","SCOTT","ANALYST","7566","1982-12-09 00:00:00","3600","","20"
"7839","KING","PRESIDENT","","1981-11-17 00:00:00","6000","","10"
"7844","TURNER","SALESMAN","7698","1981-09-08 00:00:00","1800","0","30"
"7876","ADAMS","CLERK","7788","1983-01-12 00:00:00","1320","","20"
"7900","JAMES","CLERK","7698","1981-12-03 00:00:00","1140","","30"
"7902","FORD","ANALYST","7566","1981-12-03 00:00:00","3600","","20"
"7934","MILLER","CLERK","7782","1982-01-23 00:00:00","1560","","10"

=======================================================================================================

昨天写个一个将指定表的数据导出到CSV文件的过程。想了一下,觉得通用型不好,对于不同的表还需要重新改写过程。于是今天写了一个通用的过程,可以处理任意表的任意字段,而且可以添加查询条件。


上一个例子已经介绍过UTL_FILE包了,这里就不重复了,下面直接给出代码:

SQL> CREATE DIRECTORY D_OUTPUT AS 'E:';

目录已创建。

SQL> CREATE OR REPLACE PROCEDURE P_WRITE_FILE
2 (
3 P_TABLE_NAME IN VARCHAR2, 
4 P_COLUMN_LIST IN VARCHAR2 DEFAULT NULL, 
5 P_WHERE_STR IN VARCHAR2 DEFAULT NULL) AS
6 V_FILE UTL_FILE.FILE_TYPE;
7 V_BUFFER VARCHAR2(32767);
8 V_RESULT VARCHAR2(32767);
9 C_RESULT SYS_REFCURSOR;
10 BEGIN
11 V_FILE := UTL_FILE.FOPEN('D_OUTPUT', P_TABLE_NAME || TO_CHAR(SYSDATE, 'YYYY_MM_DD') || '.csv',
'w', 32767);
12 IF P_COLUMN_LIST IS NULL THEN
13 FOR C_COLUMN IN (SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME = P_TABLE_NAME) LOOP
14 V_BUFFER := V_BUFFER || C_COLUMN.COLUMN_NAME || ',';
15 END LOOP;
16 V_BUFFER := RTRIM(V_BUFFER, ',');
17 ELSE
18 V_BUFFER := P_COLUMN_LIST;
19 END IF;
20 UTL_FILE.PUT_LINE(V_FILE, V_BUFFER);
21 V_BUFFER := REPLACE(V_BUFFER, ',', '|| ''","'' ||');
22 V_BUFFER := 'SELECT ''"'' ||' || V_BUFFER || '||''"'' RESULT FROM ' || P_TABLE_NAME;
23 IF P_WHERE_STR IS NOT NULL THEN
24 IF SUBSTR(LTRIM(P_WHERE_STR), 1, 5) != 'WHERE' THEN
25 V_BUFFER := V_BUFFER || ' WHERE';
26 END IF;
27 V_BUFFER := V_BUFFER || ' ' || P_WHERE_STR;
28 END IF;
29 OPEN C_RESULT FOR V_BUFFER;
30 LOOP
31 FETCH C_RESULT INTO V_RESULT;
32 EXIT WHEN C_RESULT%NOTFOUND;
33 UTL_FILE.PUT_LINE(V_FILE, V_RESULT);
34 END LOOP;
35 UTL_FILE.FCLOSE(V_FILE); 
36 END;
37 /

过程已创建。

SQL> EXEC P_WRITE_FILE('EMP')

PL/SQL 过程已成功完成。

得到的文件输出文件:

EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO
"7369","SMITH","CLERK","7902","17-12
-80","960","","20"
"7499","ALLEN","SALESMAN","7698","20-2
 -81","1920","300","30"
"7521","WARD","SALESMAN","7698","22-2
 -81","1500","500","30"
"7566","JONES","MANAGER","7839","02-4
 -81","3570","","20"
"7654","MARTIN","SALESMAN","7698","28-9
 -81","1500","1400","30"
"7698","BLAKE","MANAGER","7839","01-5
 -81","3420","","30"
"7782","CLARK","MANAGER","7839","09-6
月 
-81","2940","","10"
"7788","SCOTT","ANALYST","7566","09-12
-82","3600","","20"
"7839","KING","PRESIDENT","","17-11
-81","6000","","10"
"7844","TURNER","SALESMAN","7698","08-9
 -81","1800","0","30"
"7876","ADAMS","CLERK","7788","12-1
 -83","1320","","20"
"7900","JAMES","CLERK","7698","03-12
-81","1140","","30"
"7902","FORD","ANALYST","7566","03-12
-81","3600","","20"
"7934","MILLER","CLERK","7782","23-1
 -82","1560","","10"

日期现在是默认的格式,可以通过ALTER SESSION SET NLS_DATE_FORMAT的方式来改变日期的格式。

SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

会话已更改。

SQL> EXEC P_WRITE_FILE('EMP', 'EMPNO,ENAME,DEPTNO,HIREDATE')

PL/SQL 过程已成功完成。

输出文件:

EMPNO,ENAME,DEPTNO,HIREDATE
"7369","SMITH","20","1980-12-17 00:00:00"
"7499","ALLEN","30","1981-02-20 00:00:00"
"7521","WARD","30","1981-02-22 00:00:00"
"7566","JONES","20","1981-04-02 00:00:00"
"7654","MARTIN","30","1981-09-28 00:00:00"
"7698","BLAKE","30","1981-05-01 00:00:00"
"7782","CLARK","10","1981-06-09 00:00:00"
"7788","SCOTT","20","1982-12-09 00:00:00"
"7839","KING","10","1981-11-17 00:00:00"
"7844","TURNER","30","1981-09-08 00:00:00"
"7876","ADAMS","20","1983-01-12 00:00:00"
"7900","JAMES","30","1981-12-03 00:00:00"
"7902","FORD","20","1981-12-03 00:00:00"
"7934","MILLER","10","1982-01-23 00:00:00"

SQL> EXEC P_WRITE_FILE('EMP', 'EMPNO,ENAME,DEPTNO', 'WHERE DEPTNO = 30')

PL/SQL 过程已成功完成。

输出文件:

EMPNO,ENAME,DEPTNO
"7499","ALLEN","30"
"7521","WARD","30"
"7654","MARTIN","30"
"7698","BLAKE","30"
"7844","TURNER","30"
"7900","JAMES","30"

当然,过程还是有限制的,当取出的列的长度总和超过了32767,则UTL_FILE包就没有办法将内容写入文件了。这也是PL/SQLVARCHAR2类型最大容量。

不过对于大多数的情况,32767应该足够了,如果超过这个数值,恐怕就只能使用CJAVA外部过程了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Apache Commons CSV是一个Java库,可以用来读取、写入和处理CSV文件。如果你想使用它来导出字符串格式数据,可以按照以下步骤进行操作: 1. 引入依赖 在你的项目中引入Apache Commons CSV的依赖。 Maven用户可以在pom.xml中添加以下代码块: ``` <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-csv</artifactId> <version>1.8</version> </dependency> ``` Gradle用户可以在build.gradle中添加以下代码: ``` implementation 'org.apache.commons:commons-csv:1.8' ``` 2. 创建CSVPrinter对象 创建一个CSVPrinter对象来写入CSV数据到字符串中。CSVPrinter的构造函数需要一个Writer对象作为参数,可以使用StringWriter来创建一个Writer对象。 ``` StringWriter writer = new StringWriter(); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT); ``` 3. 写入数据 使用CSVPrinter的printRecord方法将数据写入CSV文件中。printRecord方法接受一个可变参数列,可以传递任意数量的值。 ``` csvPrinter.printRecord("Name", "Age", "Gender"); csvPrinter.printRecord("John", 25, "Male"); csvPrinter.printRecord("Jane", 30, "Female"); ``` 4. 获取字符串格式数据 调用StringWriter的toString方法可以获取CSV数据的字符串格式。 ``` String csvData = writer.toString(); ``` 完整的代码示例: ``` StringWriter writer = new StringWriter(); CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT); csvPrinter.printRecord("Name", "Age", "Gender"); csvPrinter.printRecord("John", 25, "Male"); csvPrinter.printRecord("Jane", 30, "Female"); String csvData = writer.toString(); ``` csvData字符串的值为: ``` Name,Age,Gender John,25,Male Jane,30,Female ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值