使用sqlplus spool导出CSV时表头重复的问题及解决方法
问题原因及解决方法
原因分析
- 参数逻辑冲突:你同时启用了SQL*Plus命令行的
-m "CSV ON DELIM ',' QUOTE ON"参数和脚本内的colsep ,、head on等CSV格式化设置,两种规则叠加后,在处理千万级超大结果集时触发了重复输出表头的异常。 - 大数据量分页阈值触发:即使设置了
pagesize 0,SQL*Plus在处理超大规模数据时,内部缓冲区或分页机制可能出现溢出,导致系统自动重置并重复输出表头。
解决方法
方法一:统一脚本配置,移除命令行冲突参数
修改执行命令,去掉-m相关CSV参数,避免逻辑冲突:
sqlplus -s user/pwd@host/sid '@sql_to_csv.sql' 'table1'
同时调整脚本参数,强化分页控制:
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; alter session set NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS.FF6'; set colsep , set headsep off set pagesize 999999 -- 设置远大于数据总行数的分页值,避免触发自动分页 set trimspool on set head on set feed off set term off set verify off set newpage none -- 禁止分页时插入空行或重置表头 spool ./Ora_Data/&1..csv select * from &1; spool off exit;
方法二:手动输出表头,完全控制显示时机
如果方法一无效,改用手动输出表头的方式,彻底避免自动重复输出:
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; alter session set NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS.FF6'; set colsep , set headsep off set pagesize 0 set trimspool on set head off -- 关闭自动表头输出 set feed off set term off set verify off set linesize 4000 -- 根据表字段总长度调整,避免换行 spool ./Ora_Data/&1..csv -- 替换为你的表实际字段名 select '字段1','字段2','字段3',... from dual; -- 输出数据 select * from &1; spool off exit;
这种方式由你完全控制表头输出时机,无论数据量多大,表头只会出现一次。
方法三:简化脚本,统一使用SQL*Plus原生CSV模式
如果偏好使用-m CSV参数,简化脚本内容以避免冲突:
修改脚本为:
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; alter session set NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS.FF6'; set pagesize 999999 set trimspool on set feed off set term off set verify off spool ./Ora_Data/&1..csv select * from &1; spool off exit;
执行命令保留-m参数:
sqlplus -s -m "CSV ON DELIM ',' QUOTE ON" user/pwd@host/sid '@sql_to_csv.sql' 'table1'
内容的提问来源于stack exchange,提问作者Xie Steven
相关产品推荐
相关产品推荐

