从bash脚本调用存储过程,ORA-01756:引用的字符串未正确终止

时间:2016-05-20 19:56:31

标签: python linux oracle bash

我试图从python脚本中的bash脚本调用存储过程。脚本调用工作正常,那里没有问题。问题在于PRIMARY_KEYS字段的参数。使用单个PK它可以正常工作,但对于多个PKA, B, C,我收到了oracle错误: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)
...

击:

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;   

作为免责声明,我已经在PLSQL UI界面中,在测试窗口中直接测试了此功能,并且它可以正常工作,具有多个PKs。在Bash中执行时我如何传递给存储过程有一个问题,我无法弄清楚。我尝试过\'\'%s\'\'\'%s\'\'\"%s\""%s"的组合,......不确定格式是什么。

提前致谢,

1 个答案:

答案 0 :(得分:0)

我要尝试的第一件事是从你的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)

来自the documentation(我的重点):

  

args 应该是一系列程序参数,或者是一个字符串。默认情况下,如果 args 是序列,则要执行的程序是 args 中的第一项。如果 args 是一个字符串,则解释与平台有关,如下所述。有关与默认行为的其他差异,请参阅shell和可执行参数。除非另有说明,否则建议将 args 作为序列传递

此外,我已删除了shell=TRUE以及对sh的调用,因为它们都可能导致并发症,对于前者security risks。您应该确保pkg_mypkg.sh可以使用适当的shebang执行。文档再次:

  

在具有shell=True的Unix上,shell默认为/bin/sh。如果 args 是一个字符串,则该字符串指定要通过shell执行的命令。这意味着字符串的格式必须与在shell提示符下键入时完全相同。这包括,例如,引用或反斜杠转义带有空格的文件名。如果 args 是序列,则第一项指定命令字符串,并且任何其他项将被视为shell本身的附加参数。

如果没有看到完整的shell脚本,很难说出可能会出现什么问题,尽管你在没有前面的$的情况下调用变量,我建议将SP文本放入文件而不是依赖于在反叛内部像heredoc一样构造。 http://shellcheck.net/可以帮助发现错误和非标准用法。