我正试图从bash脚本和python脚本调用存储过程。脚本调用工作正常,没有问题。问题在于PRIMARY_KEYS
字段的参数。对于单个PK
,它可以正常工作,但对于多个PK
,即A, B, C
,我会得到预言错误:ORA-01756: quoted string not properly terminated
Python:
...
cmd = 'sh pkg_mypkg.sh '%s' '%s' my_sp_which_adds_a_primary_key '%s'' % db_login_str db_table primary_keys
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=TRUE)
...
Bash:
DB_LOGIN_STR=$1
DB_TABLE=$2
FUNC_TO_EXEC=$3
PRIMARY_KEYS=$4
...
function my_sp_which_adds_a_primary_key() {
SP_RES=`sqlplus -silent $1 <<-EOM
...
BEGIN
pkg_mypkg.my_sp_which_adds_a_primary_key($2, $3);
END;
...
EOM`
echo $SP_RES
}
...
function main() {
case $FUNC_TO_EXEC in
"my_sp_which_adds_a_primary_key")
my_sp_which_adds_a_primary_key(DB_LOGIN_STR, DB_TABLE, PRIMARY_KEYS);;
esac
}
main
SP:
procedure my_sp_which_adds_a_primary_key(db_table in varchar2, primary_keys in varchar2)
is
begin
execute immediate 'alter table ' || db_table || ' add constraint ' || db_table || '_PK primary_key (' || primary_keys || ') parallel 8';
end my_sp_which_adds_a_primary_key;
作为免责声明,我已经在PLSQLUI界面中的测试窗口中直接测试了这个函数,它在多个PKs
的情况下运行良好。在Bash中执行时,我如何传递到存储的proc有一个问题,我无法弄清楚。我试过''%s''
、'%s'
、'"%s"
、"%s"
。。。不确定什么是正确的格式。
提前感谢
我尝试的第一件事是从Python代码中调用命令,如下所示:
cmd = ["pkg_mypkg.sh", db_login_str, db_table, "my_sp_which_adds_a_primary_key", primary_keys]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
从文件(我的重点):
args应该是程序参数的序列,或者是单个字符串。默认情况下,如果args是一个序列,则要执行的程序是args中的第一项。如果args是字符串,则解释取决于平台,如下所述。有关与默认行为的其他差异,请参阅shell和可执行文件参数。除非另有说明,否则建议将args作为序列传递。
此外,我删除了shell=TRUE
和对sh
的调用,因为它们都会导致并发症,在前者的情况下,还会带来安全风险。相反,您应该简单地确保pkg_mypkg.sh
可以通过适当的shebang执行。文档再次:
在带有
shell=True
的Unix上,shell默认为/bin/sh
。如果args是字符串,则该字符串指定要通过shell执行的命令。这意味着字符串的格式必须与在shell提示符下键入时的格式完全相同。例如,这包括引用或反斜杠转义的文件名,其中包含空格。如果args是一个序列,则第一项指定命令字符串,并且任何附加项都将被视为shell本身的附加参数。
如果没有看到完整的shell脚本,很难说可能存在什么问题,尽管您调用的变量没有前面的$
,我建议将SP文本放入文件中,而不是依赖于backticks中的类似heredoc的构造。http://shellcheck.net/可以帮助发现错误和非标准使用。