Oracle批量导出表数据到CSV文件

介绍如何使用Oracle存储过程和UTL_FILE包将多个表的数据批量导出为CSV文件,包括SQL脚本和存储过程的详细实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Oracle批量导出表数据到CSV文件


需求:把Oracle数据库中符合条件的N多表,导出成csv文本文件,并以表名.csv为文件名存放。
 
实现:通过存储过程中UTL_FILE函数来实现。导出的csv文件放入提前创建好的directory中。


使用方法:使用以下命令数据预执行的SQL脚本
 
SELECT 'EXEC sql_to_csv(''select * from ' ||T.TABLE_NAME ||
 
''',''OUT_PUT_CSV''' || ',''ODS_MDS.' || T.TABLE_NAME ||
 '.csv'');'
 FROM user_TABLES T
 
脚本说明:sql_to_csv 存储过程名;out_put_csv数据库目录名称;ODS_MDS预定义的schema名称;
 
存储过程代码如下:

CREATE OR REPLACE PROCEDURE CHENQY.SQL_TO_CSV
(
 P_QUERY IN VARCHAR2, -- PLSQL文
 P_DIR IN VARCHAR2, -- 导出的文件放置目录
 P_FILENAME IN VARCHAR2 -- CSV名
 )
 IS
  L_OUTPUT UTL_FILE.FILE_TYPE;
  L_THECURSOR INTEGER DEFAULT DBMS_SQL.OPEN_CURSOR;
  L_COLUMNVALUE VARCHAR2(4000);
  L_STATUS INTEGER;
  L_COLCNT NUMBER := 0;
  L_SEPARATOR VARCHAR2(1);
  L_DESCTBL DBMS_SQL.DESC_TAB;
  P_MAX_LINESIZE NUMBER := 32000;
BEGIN
  --OPEN FILE
  L_OUTPUT := UTL_FILE.FOPEN(P_DIR, P_FILENAME, 'W', P_MAX_LINESIZE);
  --DEFINE DATE FORMAT
  EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT=''YYYY-MM-DD HH24:MI:SS''';
  --OPEN CURSOR
  DBMS_SQL.PARSE(L_THECURSOR, P_QUERY, DBMS_SQL.NATIVE);
  DBMS_SQL.DESCRIBE_COLUMNS(L_THECURSOR, L_COLCNT, L_DESCTBL);
  --DUMP TABLE COLUMN NAME
  FOR I IN 1 .. L_COLCNT LOOP
    UTL_FILE.PUT(L_OUTPUT,L_SEPARATOR || '"' || L_DESCTBL(I).COL_NAME || '"'); --输出表字段
    DBMS_SQL.DEFINE_COLUMN(L_THECURSOR, I, L_COLUMNVALUE, 4000);
    L_SEPARATOR := ',';
  END LOOP;
  UTL_FILE.NEW_LINE(L_OUTPUT); --输出表字段
  --EXECUTE THE QUERY STATEMENT
  L_STATUS := DBMS_SQL.EXECUTE(L_THECURSOR);
 
  --DUMP TABLE COLUMN VALUE
  WHILE (DBMS_SQL.FETCH_ROWS(L_THECURSOR) > 0) LOOP
    L_SEPARATOR := '';
    FOR I IN 1 .. L_COLCNT LOOP
      DBMS_SQL.COLUMN_VALUE(L_THECURSOR, I, L_COLUMNVALUE);
      UTL_FILE.PUT(L_OUTPUT,
                  L_SEPARATOR || '"' ||
                  TRIM(BOTH ' ' FROM REPLACE(L_COLUMNVALUE, '"', '""')) || '"');
      L_SEPARATOR := ',';
    END LOOP;
    UTL_FILE.NEW_LINE(L_OUTPUT);
  END LOOP;
  --CLOSE CURSOR
  DBMS_SQL.CLOSE_CURSOR(L_THECURSOR);
  --CLOSE FILE
  UTL_FILE.FCLOSE(L_OUTPUT);
EXCEPTION
  WHEN OTHERS THEN
    RAISE;
END;
 
/

更多Oracle相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12

本文永久更新链接地址http://www.linuxidc.com/Linux/2014-07/104464.ht
m

其他参考:

Oracle AWR报告生成与查看 http://www.linuxidc.com/Linux/2011-04/34397.htm

CentOS 6.4下安装Oracle 11gR2(x64) http://www.linuxidc.com/Linux/2014-02/97374.htm

Oracle 11gR2 在VMWare虚拟机中安装步骤 http://www.linuxidc.com/Linux/2013-09/89579p2.htm

Debian 下 安装 Oracle 11g XE R2 http://www.linuxidc.com/Linux/2014-03/98881.htm

Oracle AWR报告生成步骤 http://www.linuxidc.com/Linux/2014-06/102685.htm

Oracle数据库表导出和导入csv文件操作  http://www.linuxidc.com/Linux/2011-10/44816.htm


### Oracle 批量加载 CSV 文件时跳过错误的解决方案 在处理大规模数据导入操作时,可能会因为某些记录不符合目标结构而导致整个批处理失败。为了实现批量加载过程中忽略特定类型的错误并继续执行后续记录的操作,在 Oracle 数据库中可以采用 `SQL*Loader` 或者 PL/SQL 脚本配合异常捕获机制来完成。 以下是两种常见的方法: #### 方法一:使用 SQL*Loader 的 ERROR 和 DISCARDED 参数 通过配置 SQL*Loader 控制文件中的参数选项,能够指定允许的最大错误数以及定义如何处理无法解析的数据行。具体设置如下所示[^2]: ```sql OPTIONS (SKIP=1, ERRORS=5000, DIRECT=TRUE) LOAD DATA INFILE 'data.csv' INTO TABLE target_table FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS ( column1, column2, column3 ) BADFILE 'bad_records.bad' DISCARDFILE 'discarded_rows.dsc' ``` 上述脚本实现了以下功能: - **SKIP**: 忽略前几条记录(通常用于跳过标题行)。 - **ERRORS**: 定义可接受的最大错误数量;超过此限制则终止加载过程。 - **DIRECT=true**: 启用直接路径模式以提高性能。 - **BADFILE/DISCARDFILE**: 将有问题或者被丢弃的记录保存到单独的日志文件里以便事后审查。 #### 方法二:利用外部与 INSERT IGNORE 结合 创建一个基于输入 CSV 文件的外部,并将其作为中间层映射至实际的目标存储对象上。接着编写一条带有条件过滤逻辑的INSERT语句,从而有效规避那些引发冲突的关键字段组合实例[^3]。 第一步,先建立外部描述源数据布局: ```sql CREATE TABLE ext_tab ( col_a VARCHAR2(50), col_b NUMBER, col_c DATE ) ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY data_dir ACCESS PARAMETERS ( RECORDS DELIMITED BY NEWLINE CHARACTERSET UTF8 BADFILE bad_data:'err%a_%p.bad' LOGFILE log_data:'log%a_%p.log' FIELDS TERMINATED BY ',' MISSING FIELD VALUES ARE NULL REJECT ROW WITH ALL NULL FIELDS ) LOCATION ('input_file.csv') ); ``` 第二步,实施插入动作的同时附加额外验证措施防止重复键或其他违反约束的情况发生: ```sql BEGIN FOR rec IN (SELECT * FROM ext_tab WHERE NOT EXISTS(SELECT 1 FROM real_tab rt WHERE rt.pk_col = et.col_a)) LOOP BEGIN INSERT INTO real_tab(col_x,col_y,col_z) VALUES(rec.col_a,rec.col_b,rec.col_c); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN -- Duplicate value found; do nothing and continue processing next row. NULL; END; END LOOP; END; / ``` 以上代码片段展示了如何遍历来自外部的结果集并通过逐项评估决定哪些应该加入最终集合之中。如果检测到主键碰撞等问题,则简单地忽略该情况而不中断整体流程运行。 #### 注意事项 无论采取哪种方式都需要提前规划好相应的备份策略以防万一出现问题影响原始资料的安全性。另外还需注意调整系统资源配额比如临时段大小等可能会影响大批量事务效率的因素[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值