使用Cursor生成CSV时,如何避免列中逗号分隔值被拆分?
问题解决:PL/SQL生成CSV时含逗号字段被拆分的修复
问题原因
你的代码直接用逗号拼接两列内容,当VISUAL_COMMENTS字段本身包含逗号时,CSV解析器会把这个逗号当成列分隔符,导致字段被拆分成多列,不符合预期。CSV格式要求:字段包含逗号、双引号、换行符时,必须用双引号包裹,字段内的双引号需要转义为两个双引号。
解决方案
1. 创建CSV字段转义辅助函数
先编写一个通用函数处理字段的转义逻辑:
CREATE OR REPLACE FUNCTION GISPROD.FORMAT_CSV_FIELD(p_field IN VARCHAR2) RETURN VARCHAR2 IS BEGIN IF p_field IS NULL THEN RETURN ''; END IF; -- 转义字段内的双引号:替换为两个双引号 -- 用双引号包裹字段,处理含逗号、换行、引号的情况 RETURN '"' || REPLACE(p_field, '"', '""') || '"'; END FORMAT_CSV_FIELD; /
2. 修改存储过程代码
修正游标查询逻辑,用辅助函数处理字段,同时修正换行符的拼接位置:
CREATE OR REPLACE PROCEDURE GISPROD.POLE_CSV IS vc_mess VARCHAR2(32600); crlf VARCHAR2(2) := CHR(13) || CHR(10); vc_headings VARCHAR2(500) := FORMAT_CSV_FIELD('VISUAL_COMMENTS') || ',' || FORMAT_CSV_FIELD('POLE_STRENGTH'); file_name VARCHAR2(100) := 'POLE_Report_' || TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') || '.csv'; conn utl_smtp.connection; BEGIN -- 先写入表头 lh_mail.write_text( conn => conn, message => vc_headings ); -- 遍历数据行 FOR rec IN ( SELECT FORMAT_CSV_FIELD(VISUAL_COMMENTS) || ',' || FORMAT_CSV_FIELD(POLE_STRENGTH) || crlf AS eline FROM table_name WHERE import_date IS NOT NULL ORDER BY inspect_date DESC, import_date ) LOOP lh_mail.write_text( conn => conn, message => rec.eline ); END LOOP; END POLE_CSV; /
关键修改点
- 用
FORMAT_CSV_FIELD函数处理每个字段,确保含特殊字符的字段被双引号包裹,内部双引号转义 - 表头也用同一函数处理,保持格式统一
- 把换行符
crlf加到每行的末尾,修正原代码中换行符的错误位置
内容的提问来源于stack exchange,提问作者Tapan
相关产品推荐
相关产品推荐

