因此,我尝试通过将要执行的脚本包装在“页眉”和“页脚”中,将一些默认配置应用于每次调用
sqlplus
,以便获得一致的执行。
但是,当我实现这个 bash 函数时,我意识到某些脚本具有参数,并且当我尝试将它们传递给
sqlplus
并使用定界文档进行“包装”时,sqlplus 会感到困惑并认为参数意味着替换是实际的(sqlplus)。
那么,除了创建临时文件之外,有没有办法仍然使用heredoc(或任何标准输入流,如
envsubst
)以及脚本参数?
下面的代码(将其源到文件中或简单地将函数复制并粘贴到交互式 shell 中):
function exec_sql_file(){
local sql_file=${1:?You must supply and sql_file file to execute}
local script_dir username password
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
source "${script_dir}/omc.env"
local script="${script_dir}/sql/${sql_file}"
sqlplus -s "$username/$password@sredb1_high" <<-EOF "${@:2}" | tail -n "+$#"
set heading off;
set feedback off;
set linesize 10000;
set newpage NONE;
set colsep '|'
$(cat "${script}")
exit;
EOF
} && export -f exec_sql_file
示例.sql:
select &1 + &2 from dual
预期用途:
exec_sql_file queries/example.sql 1 3
4
需要的是heredoc后面的
"${@:2}"
它尝试执行的名义 cli 是:
sqlplus -s "$username/$password@sredb1_high" @sql/queries/example.sql 1 3
这是一个带有临时文件的工作功能示例(不是我的偏好)
function exec_sql_file(){
local sql_file=${1:?You must supply and sql_file file to execute}
local script_dir username password
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
local env_file="${script_dir}/omc.env"
source "${script_dir}/omc.env"
local script="${script_dir}/sql/${sql_file}"
local tmpFile
tmpFile=$(mktemp)
cat <<-EOF > "${tmpFile}"
set heading off;
set feedback off;
set linesize 10000;
set newpage NONE;
set colsep '|'
$(cat "${script}")
exit;
EOF
echo exit | sqlplus -s "$username/$password@sredb1_high" "@${tmpFile}" "${@:2}" |
tail -n "+$#" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
} && export -f exec_sql_file
heredoc 改变了 stdin 的指向。它不会充当或变成命令行参数,因此将参数放在heredoc之后(或在heredoc之前)的想法没有任何意义:heredocs不参与命令行参数排序.