使用 UTL_FILE导出TAB和逗号分割数据

本文介绍使用PL/SQL过程将Oracle数据库中的特定查询结果导出到文本文件的方法。包括设置查询语句、利用UTL_FILE包进行文件操作及通过游标循环读取并写入数据的具体步骤。
DECLARE
  row_result varchar2(4000);
  selectsql  varchar2(4000);
  qrycursor  SYS_REFCURSOR;
  txt_handle UTL_FILE.file_type;
BEGIN
  selectsql  := 'select USER_ID||chr(9)||EXTERNAL_ID||chr(9)||ACCOUNT_ID||chr(9)||CERTIFY_STATUS||chr(9)||USER_STATUS||chr(9)||RUNTIME_STATUS||chr(9)||USER_NAME||chr(9)||REAL_NAME||chr(9)||COUNTRY||chr(9)||GENDER||chr(9)||PROFESSION||chr(9)||ADDRESS||chr(9)||PHONE||chr(9)||MOBILE||chr(9)||EMAIL||chr(9)||CERT_TYPE||chr(9)||CERT_NO||chr(9)||LICENSE_VALID_TIME||chr(9)||REGISTER_FROM||chr(9)||ORIGIN_REGISTER_FROM||chr(9)||RAW_ADD_TIME||chr(9)||RAW_UPDATE_TIME||chr(9)||BANK_CARD_NO||chr(9)||BANK_CARD_TYPE||chr(9)||NAME||chr(9)||BANK_CERT_NO from yhcheck.til_per';
  txt_handle := UTL_FILE.FOPEN('TESTDIR', 'b.txt', 'w',32767);
  open qrycursor for selectsql;
  loop
    fetch qrycursor
      into row_result;
    exit when qrycursor%notfound;
    UTL_FILE.PUT_LINE(txt_handle, row_result);
  end loop;
  --关闭游标    
  close qrycursor;
  UTL_FILE.FCLOSE(txt_handle);
end;

逗号分隔
DECLARE
  row_result varchar2(4000);
  selectsql  varchar2(4000);
  qrycursor  SYS_REFCURSOR;
  txt_handle UTL_FILE.file_type;
BEGIN
  selectsql  := 'select id || '','' || name || '','' || dti
  from testdump
 where name = ''gaopeng''
   and dti > to_date(''2015-03-17 00:00:00'', ''yyyy-mm-dd hh24:mi:ss'')';
  txt_handle := UTL_FILE.FOPEN('DATA_PUMP_DIR', 'b.txt', 'w', 32767);
  open qrycursor for selectsql;
  loop
    fetch qrycursor
      into row_result;
    exit when qrycursor%notfound;
    UTL_FILE.PUT_LINE(txt_handle, row_result);
  end loop;
  --关闭游标    
  close qrycursor;
  UTL_FILE.FCLOSE(txt_handle);
end;



注意点 1:'w'可以更改为'a'为追加
         2:32767为每行的宽度,默认为1024
         3:TESTDIR为大写是 CREATE DIRECTORY建立的目录
         4: chr(9) 为TAB分割
CREATE OR REPLACE PROCEDURE dump_table_to_csv (p_tname IN VARCHAR2, p_dir IN VARCHAR2, p_filename IN VARCHAR2) IS l_output UTL_FILE.file_type; l_theCursor INTEGER DEFAULT DBMS_SQL.open_cursor; l_columnValue VARCHAR2 (4000); l_status INTEGER; l_query VARCHAR2 (1000) DEFAULT 'select * from ' || p_tname; l_colCnt NUMBER := 0; l_separator VARCHAR2 (1); l_descTbl DBMS_SQL.desc_tab; BEGIN l_output := UTL_FILE.fopen (p_dir, p_filename, 'w'); EXECUTE IMMEDIATE 'alter session set nls_date_format=''yyyy-mm-dd hh24:mi:ss'' '; DBMS_SQL.parse (l_theCursor, l_query, DBMS_SQL.native); DBMS_SQL.describe_columns (l_theCursor, l_colCnt, l_descTbl); FOR i IN 1 .. l_colCnt LOOP DBMS_SQL.define_column (l_theCursor, i, l_columnValue, 4000); END LOOP; l_status := DBMS_SQL.execute (l_theCursor); 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 || l_columnValue); l_separator := ','; END LOOP; UTL_FILE.new_line (l_output); END LOOP; DBMS_SQL.close_cursor (l_theCursor); UTL_FILE.fclose (l_output); EXECUTE IMMEDIATE 'alter session set nls_date_format=''dd-MON-yy'' '; EXCEPTION WHEN OTHERS THEN EXECUTE IMMEDIATE 'alter session set nls_date_format=''dd-MON-yy'' '; RAISE; END; 这个是oracle的存储过程,我想要把它给转成postgreSql的。其中我postgreSql的数据库里所有的表名字段都是小写的,但是我转成postgreSql的这个存储过程的名字我还是希望保留着大写的。还有就是你还要给出我这两种数据库的存储过程的运行方法以及查询结果方法,像 “ postgreSQL: CALL "SP_CREATE_RP_GRPSVRWORK_CNT"('2024-03-04'::timestamp, '2024-03-05'::timestamp); -- 或者指定具体日期范围 SELECT * FROM rp_grpsvrworkcnt WHERE offhktm BETWEEN '2024-03-04' AND '2024-03-05' ORDER BY offhktm DESC; oracle: BEGIN SP_CREATE_RP_GRPSVRWORK_CNT(TO_DATE('2024-03-04', 'YYYY-MM-DD'), TO_DATE('2024-03-05', 'YYYY-MM-DD')); END; SELECT * FROM RP_GRPSVRWORKCNT WHERE OFFHKTM BETWEEN TO_DATE('2024-03-04', 'YYYY-MM-DD') AND TO_DATE('2024-03-05', 'YYYY-MM-DD') ORDER BY OFFHKTM DESC; ”这样
03-12
<think>好的,我现在需要帮助用户找到在Oracle 19c中使用UTL_FILE导出数据的存储过程示例。首先,我得回忆一下UTL_FILE的基本用法相关注意事项。用户提到了他们之前遇到的GoldenGate错误,可能他们在配置复制或导出时遇到了权限或参数设置的问题,不过当前问题主要集中在UTL_FILE上。 首先,UTL_FILE包主要用于在数据库服务器上读写操作系统文件。用户需要导出数据,所以应该使用写文件的步骤。我需要确保他们了解必要的目录对象创建,因为Oracle不能直接访问文件系统路径,必须通过DIRECTORY对象来授权。 接下来,存储过程的结构大概包括创建目录、授权、编写存储过程,然后测试执行。需要提醒用户关于目录路径的权限,以及数据库参数utl_file_dir是否设置,不过Oracle 19c可能更推荐使用DIRECTORY对象而不是该参数。另外,用户提到的GoldenGate错误可能与当前问题无关,但可能需要检查是否还有其他配置问题。 然后,我需要提供一个示例代码,展示如何创建目录对象,如何用存储过程将查询结果导出到CSV文件。示例中应该包含打开文件、循环读取数据并写入、异常处理等部分。同时,需要注意字符集换行符的问题,确保生成的文件格式正确。 用户可能还需要知道如何调度这个存储过程,比如使用DBMS_SCHEDULER定期执行。此外,权限方面,用户需要具有CREATE ANY DIRECTORY的权限,或者由DBA创建目录并授予读写权限。可能还需要注意导出文件的位置是否在数据库服务器上,而不是客户端机器。 最后,生成相关问题时要围绕UTL_FILE的其他功能、权限处理、大文件导出、与GoldenGate错误的关系等方面。确保覆盖用户可能进一步询问的点,比如性能优化或不同数据格式的处理。</think>在Oracle 19c中使用UTL_FILE包实现数据导出的存储过程,需遵循以下步骤: ### 1. 创建目录对象(需DBA权限) ```sql CREATE OR REPLACE DIRECTORY EXPORT_DIR AS '/u01/app/oracle/exports'; GRANT READ, WRITE ON DIRECTORY EXPORT_DIR TO your_user; ``` ### 2. 基础存储过程示例 ```sql CREATE OR REPLACE PROCEDURE export_emp_data IS file_handle UTL_FILE.FILE_TYPE; CURSOR emp_cur IS SELECT * FROM employees; emp_rec emp_cur%ROWTYPE; BEGIN file_handle := UTL_FILE.FOPEN('EXPORT_DIR', 'employee_data.csv', 'W', 32767); -- 写入表头 UTL_FILE.PUT_LINE(file_handle, 'EMP_ID,NAME,SALARY,DEPT_ID'); OPEN emp_cur; LOOP FETCH emp_cur INTO emp_rec; EXIT WHEN emp_cur%NOTFOUND; -- 写入数据UTL_FILE.PUT_LINE(file_handle, emp_rec.employee_id || ',' || emp_rec.last_name || ',' || emp_rec.salary || ',' || emp_rec.department_id ); END LOOP; CLOSE emp_cur; UTL_FILE.FCLOSE(file_handle); EXCEPTION WHEN OTHERS THEN IF UTL_FILE.IS_OPEN(file_handle) THEN UTL_FILE.FCLOSE(file_handle); END IF; RAISE; END; / ``` ### 3. 关键参数说明 - `FOPEN`模式参数:支持`R`(读)、`W`(覆盖写)、`A`(追加写) - 字符集:建议使用`AL32UTF8`参数处理多语言数据 - 文件权限:注意Oracle进程用户对目录的OS级权限 ### 4. 执行存储过程 ```sql BEGIN export_emp_data(); END; / ``` 注意:若出现`ORA-29280`错误,请检查: 1. 目录对象路径是否存在 2. Oracle用户是否有OS级写权限 3. `EXPORT_DIR`是否已正确授权[^1] ### 5. 扩展功能建议 - 使用`DBMS_SCHEDULER`设置定时导出任务 - 添加日期时间戳生成动态文件名 - 使用`NLS_NUMERIC_CHARACTERS`处理数字格式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值