通过Shell执行.sql文件无法生成有效CSV文件问题求助
Shell调用sqlplus生成CSV为空的解决方案
- 优先检查脚本执行环境的变量是否完整
你脚本中使用的$SRC、$DB_LOGIN这类自定义变量,很可能在脚本运行环境中未被正确加载。大多数定时任务或者非交互式执行Shell的场景,不会自动加载用户目录下的.bash_profile、.bashrc等配置文件,导致变量为空。比如$SRC为空的话,@$SRC/sql_to_run.sql实际会变成@/sql_to_run.sql,找不到对应SQL文件自然没有输出。
可以在调用sqlplus前增加变量校验逻辑:# 校验SQL文件是否存在 if [ ! -f "${SRC}/sql_to_run.sql" ]; then echo "SQL文件不存在,SRC变量值为:${SRC}" >> ${LOGFILE} exit 1 fi # 校验数据库登录变量是否非空 if [ -z "${DB_LOGIN}" ]; then echo "数据库登录变量DB_LOGIN未配置" >> ${LOGFILE} exit 1 fi - 调整sqlplus的输出配置,捕获完整执行日志
你当前关闭了echo、feedback等输出配置,同时只重定向了标准输出到日志,SQL执行报错、找不到文件这类信息很可能没被记录到日志中,才会出现没有ORA错误的假象。可以临时修改sqlplus调用逻辑,打开输出方便排查:
执行后查看日志就能看到SQL是否被正常加载、是否有返回行数、具体报错信息。# 把stderr也重定向到日志,同时临时打开echo和feedback输出 sqlplus -s $DB_LOGIN<<EOSQL >>${LOGFILE} 2>&1 SET echo ON SET feedback ON SET sqlprompt '' SET TERMOUT OFF SET UNDERLINE OFF SET trimspool ON SET trimout ON SET SQLBLANKLINES ON SET PAGESIZE 50000 SET COLSEP "|" SET LINESIZE 650 SPOOL $dest_loc/$FILE @$SRC/sql_to_run.sql SPOOL OFF EOSQL - 检查输出目录的写入权限
确认脚本执行用户对$dest_loc路径有读写权限,权限不足的场景下可能会生成空文件但无法写入查询结果,可以在脚本中增加写入测试:if ! touch "${dest_loc}/write_test.tmp" || ! echo "test" > "${dest_loc}/write_test.tmp"; then echo "输出路径${dest_loc}无写入权限" >> ${LOGFILE} exit 1 fi rm -f "${dest_loc}/write_test.tmp" - 校验SQL执行的上下文一致性
确认脚本中$DB_LOGIN对应的数据库用户、权限,和你直接执行SQL时使用的用户一致,避免因为权限不足无法访问表数据但被关闭的输出配置隐藏了报错。如果SQL中有用到会话级参数、绑定变量,要确保脚本执行时也做了对应配置。
内容的提问来源于stack exchange,提问作者Serotonin
相关产品推荐
相关产品推荐

