如何用Shell脚本将指定SQL查询结果含表头导出为CSV文件
用Shell脚本导出Oracle SQL查询结果(带表头)到CSV
我整理了两个实用的Shell脚本方案,帮你把指定的Oracle查询结果连同表头导出成CSV文件,完美适配你给出的SQL语句:
方案一:sqlplus直接输出结构化CSV(处理特殊字符)
这个方案会自动处理字段里的逗号、双引号等特殊字符,用双引号包裹每个字段,避免CSV格式混乱:
#!/bin/bash # 数据库连接信息,请根据实际情况修改 DB_USER="your_username" DB_PWD="your_password" DB_TNS="your_tns_or_host:port/service_name" OUTPUT_CSV="/path/to/your/output.csv" # 完整的SQL查询语句(记得补全你截断的backout_fla条件) SQL_QUERY="SELECT SourceIdentifier, SourceFileName, ProfitCentre2, PlantCode, tax_retur ReturnPeriod, document_number DocumentNumber, TO_CHAR(invoice_generation_date,'YYYY-MM-DD') Docume, Original, customer_name CustomerName, NVL(sns_pos,new_state_code) POS, PortCode, NEW_HSN_CODE HSNorSAC, (SGSATE+UTGSATE) Stat, (SGS+UT) StateUT, Userde FROM arbor.INV_REPO_FINA WHERE UPPER(document_type)='INV' AND UPPER(backout_fla) = 'N' -- 这里补全你的完整条件 " # 用sqlplus执行查询并导出CSV sqlplus -s ${DB_USER}/${DB_PWD}@${DB_TNS} << EOF SET HEADING OFF SET FEEDBACK OFF SET LINESIZE 4000 SET TRIMSPOOL ON SET PAGESIZE 0 SET COLSEP ',' -- 先输出表头(和查询字段别名完全对应) SELECT '"SourceIdentifier","SourceFileName","ProfitCentre2","PlantCode","ReturnPeriod","DocumentNumber","Docume","Original","CustomerName","POS","PortCode","HSNorSAC","Stat","StateUT","Userde"' FROM DUAL; -- 输出查询结果,每个字段用双引号包裹,转义内部双引号 SELECT '"'||REPLACE(SourceIdentifier, '"', '""')||'"', '"'||REPLACE(SourceFileName, '"', '""')||'"', '"'||REPLACE(ProfitCentre2, '"', '""')||'"', '"'||REPLACE(PlantCode, '"', '""')||'"', '"'||REPLACE(tax_retur, '"', '""')||'"', '"'||REPLACE(document_number, '"', '""')||'"', '"'||REPLACE(TO_CHAR(invoice_generation_date,'YYYY-MM-DD'), '"', '""')||'"', '"'||REPLACE(Original, '"', '""')||'"', '"'||REPLACE(customer_name, '"', '""')||'"', '"'||REPLACE(NVL(sns_pos,new_state_code), '"', '""')||'"', '"'||REPLACE(PortCode, '"', '""')||'"', '"'||REPLACE(NEW_HSN_CODE, '"', '""')||'"', '"'||REPLACE((SGSATE+UTGSATE), '"', '""')||'"', '"'||REPLACE((SGS+UT), '"', '""')||'"', '"'||REPLACE(Userde, '"', '""')||'"' FROM arbor.INV_REPO_FINA WHERE UPPER(document_type)='INV' AND UPPER(backout_fla) = 'N' -- 补全条件 / EOF > ${OUTPUT_CSV} echo "CSV文件已成功生成:${OUTPUT_CSV}"
关键说明:
-s参数让sqlplus以静默模式运行,避免输出多余的欢迎/退出信息REPLACE(字段名, '"', '""')处理字段内的双引号,符合CSV格式规范(双引号需要转义为两个双引号)- 手动输出表头确保和查询结果的列完全对应,避免sqlplus默认表头的格式问题
方案二:用spool命令批量导出(适合大结果集)
如果你的查询结果行数很多,用spool会更稳定,避免输出缓冲区溢出:
#!/bin/bash DB_USER="your_username" DB_PWD="your_password" DB_TNS="your_tns_or_host:port/service_name" OUTPUT_CSV="/path/to/your/output.csv" TEMP_SQL="/tmp/temp_export.sql" # 生成临时SQL脚本 cat > ${TEMP_SQL} << EOF SET HEADING OFF SET FEEDBACK OFF SET LINESIZE 4000 SET TRIMSPOOL ON SET PAGESIZE 0 SET COLSEP ',' SPOOL ${OUTPUT_CSV} -- 输出表头 SELECT '"SourceIdentifier","SourceFileName","ProfitCentre2","PlantCode","ReturnPeriod","DocumentNumber","Docume","Original","CustomerName","POS","PortCode","HSNorSAC","Stat","StateUT","Userde"' FROM DUAL; -- 输出查询结果 SELECT '"'||REPLACE(SourceIdentifier, '"', '""')||'"', '"'||REPLACE(SourceFileName, '"', '""')||'"', '"'||REPLACE(ProfitCentre2, '"', '""')||'"', '"'||REPLACE(PlantCode, '"', '""')||'"', '"'||REPLACE(tax_retur, '"', '""')||'"', '"'||REPLACE(document_number, '"', '""')||'"', '"'||REPLACE(TO_CHAR(invoice_generation_date,'YYYY-MM-DD'), '"', '""')||'"', '"'||REPLACE(Original, '"', '""')||'"', '"'||REPLACE(customer_name, '"', '""')||'"', '"'||REPLACE(NVL(sns_pos,new_state_code), '"', '""')||'"', '"'||REPLACE(PortCode, '"', '""')||'"', '"'||REPLACE(NEW_HSN_CODE, '"', '""')||'"', '"'||REPLACE((SGSATE+UTGSATE), '"', '""')||'"', '"'||REPLACE((SGS+UT), '"', '""')||'"', '"'||REPLACE(Userde, '"', '""')||'"' FROM arbor.INV_REPO_FINA WHERE UPPER(document_type)='INV' AND UPPER(backout_fla) = 'N'; -- 补全条件 SPOOL OFF EXIT; EOF # 执行临时SQL脚本 sqlplus -s ${DB_USER}/${DB_PWD}@${DB_TNS} @${TEMP_SQL} # 清理临时文件 rm -f ${TEMP_SQL} echo "CSV文件已成功生成:${OUTPUT_CSV}"
额外注意事项:
- 如果字段包含换行符,可添加
REPLACE(字段名, CHR(10), '')去掉换行符,避免CSV格式错乱 - 确保运行脚本的用户有访问
arbor.INV_REPO_FINA表的查询权限 - 若遇到中文乱码,可在sqlplus配置中添加
SET NLS_LANG=AMERICAN_AMERICA.AL32UTF8(根据实际数据库编码调整)
内容的提问来源于stack exchange,提问作者as7951
相关产品推荐
相关产品推荐

