CSV导出需统一处理分隔符与换行符:字段含双引号须转义为两个双引号,含换行须整体加引号;SQL Server推荐bcp加-c -t"," -r"\n" -k -C 65001,Oracle推荐SQL*Plus配SET COLSEP ","、LINESIZE 32767及TRIMSPOOL ON。
导出时字段分隔符和换行符必须统一处理
oracle 或 sql server 导出 csv 时,to_char、convert 等函数默认不处理换行符或双引号,导致 csv 解析失败。比如 sql server 的 for xml path 或 oracle 的 utl_file 都可能把字段里的 \n 或 " 直接写入,而标准 csv 要求:字段含双引号需用两个双引号转义,含换行需整个字段用双引号包裹。
实操建议:
- SQL Server 推荐用
bcp命令加-c -t"," -r"\n",但务必加-k(保留空值)和-C 65001(UTF-8 编码) - Oracle 推荐用 SQL*Plus +
SET COLSEP ",",但需提前SET LINESIZE 32767和SET TRIMSPOOL ON,否则字段截断 - 所有导出前,在 SELECT 中对字符串字段做清洗:
REPLACE(REPLACE(col, '"', '""'), CHR(10), ' ') || ''(Oracle)或REPLACE(REPLACE(col, '"', '""'), CHAR(10), ' ')(SQL Server)
中文乱码问题本质是编码不匹配
导出的 CSV 打开是乱码,不是“没设置 UTF-8”,而是工具链里至少一处用了非 UTF-8 编码:数据库客户端字符集、导出命令环境变量、甚至 Excel 默认打开方式。Excel 本身不识别 UTF-8 BOM,直接双击会按系统 ANSI 解码。
实操建议:
- SQL Server:确认数据库排序规则是
Chinese_PRC_CI_AS或类似,连接字符串加ApplicationIntent=ReadOnly;Charset=utf8;(若用 ODBC) - Oracle:检查
NLS_LANG环境变量是否为AMERICAN_AMERICA.AL32UTF8;导出时用sqlplus /nolog进入后先执行SET NLS_LANG=AMERICAN_AMERICA.AL32UTF8 - 终极保险:导出后用
iconv -f GBK -t UTF-8 input.csv > output.csv(Linux/macOS),或用 Python 一行修复:open('out.csv','w',encoding='utf-8').write(open('in.csv',encoding='gbk').read())
NULL、空字符串、空白字段在 CSV 中表现不同
CSV 没有类型定义,NULL、空字符串 ''、全空格字符串 ' ' 全部变成空字段 ,,,下游解析时无法区分。尤其 Oracle 的 NULL 和 SQL Server 的 NULL 在导出时都变成空,但业务上意义完全不同。
实操建议:
- 显式转换 NULL:SQL Server 用
ISNULL(col, 'NULL'),Oracle 用NVL(col, 'NULL')—— 注意加单引号避免被误判为数字 - 空字符串也统一替换:
NULLIF(LTRIM(RTRIM(col)), '')再套一层 NVL/ISNULL,避免空格干扰 - 如果下游是 Python pandas,导入时加参数:
pd.read_csv(..., na_values=['NULL'], keep_default_na=False)
大表导出卡死或内存溢出怎么办
直接 SELECT * INTO OUTFILE(MySQL)或 SSMS“导出向导”对千万级表基本不可行:SQL Server 会把整结果集加载进内存再写文件;Oracle 的 SQL*Plus 默认每页 fetch 15 行,但缓冲区未调大会频繁 I/O。
实操建议:
- SQL Server:用
bcp "SELECT ... FROM tbl WHERE id BETWEEN ? AND ?" queryout chunk.csv -c -t","分批导出,配合ROW_NUMBER()切片 - Oracle:用 PL/SQL 写游标循环,每次 fetch 10000 行,用
UTL_FILE.PUT_LINE写入,避免单次大结果集 - 绕过数据库直连:用 Logstash 或 Apache NiFi,它们内置分页和流式写 CSV,不依赖 DB 内存
最常被忽略的是字段长度超限——比如 Oracle 的 VARCHAR2(4000) 字段实际内容只有 200 字符,但导出时仍按 4000 占位,导致 CSV 文件体积虚高、解析变慢。导出前务必确认真实数据长度分布。


















