在将1个字符变量从sqlplus传递给shell时,我发现这个令人讨厌的异常现象。
echo "Please enter the upgrade option: "
read type
if [[ "$type" != "1" ]] && [[ "$type" != "2" ]]
then
echo "You have entered an invalid response. Exiting."
exit 0;
fi
sql_result=$($ORACLE_HOME/bin/sqlplus -s /nolog <<-EOF
connect $eval_user/$eval_pass@$db_name
SPOOL results.txt;
WHENEVER OSERROR EXIT 9;
DEFINE vType = '$type'
DEFINE type_flag = '$t_flag'
DEFINE vOrigowner = '$origOwner'
@@EV_DBUPGRADE.sql '&vType' '&vOrigowner' '&vAppConvFromDt' '&vAppConvThruDt' '&vAppConvStatusFlg' '&type_flag'
在EV_DBUPGRADE.sql下,我在使用变量vType时发现此错误:
vOption varchar2(1) := UPPER('&1');
我得到这个令人讨厌的错误,抱怨缓冲区长度
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 7
如果使用varchar2(10),则不会发生错误。但是,我不想在百万个不同的地方改变它。反正有限制吗?谁能告诉我如何在BEGIN之外的sqlplus中打印调试消息?
答案 0 :(得分:2)
我不确定这里到底发生了什么,但shell正在为你的shell变量做些什么。
我能够在ksh(“testme.ksh”)
中复制你的错误#!/bin/ksh
type="1"
sqlresult=$($ORACLE_HOME/bin/sqlplus -s /nolog << EOF
connect user/pswd@database
define vType = '$type'
@test.sql &vType
exit
/
EOF)
echo $sqlresult
SQL脚本(“test.sql”):
declare
vOption varchar2(1) := UPPER('&1');
begin
dbms_output.put_line('Test: ' || vOption);
end;
/
输出:
Connected. old 2: vOption varchar2(1) := UPPER('&1'); new 2: vOption varchar2(1)
:= UPPER('$type'); declare test.sql testme.ksh ERROR at line 1: ORA-06502: PL/SQ
L: numeric or value error: character string buffer too small ORA-06512: at line
2
我不确定为什么会这样,但我能够通过将shell变量直接传递给SQL脚本执行并绕过“define”语句来解决它:
#!/bin/ksh
type="1"
sqlresult=$($ORACLE_HOME/bin/sqlplus -s /nolog << EOF
connect user/pswd@database
@test.sql $type
exit
/
EOF)
echo $sqlresult
输出:
Connected. old 2: vOption varchar2(1) := UPPER('&1'); new 2: vOption varchar2(1)
:= UPPER('1'); PL/SQL procedure successfully completed.
答案 1 :(得分:1)
好吧,似乎rgettman有实际的答案,但我会留下这里关于prompt
...
添加调试的快速版本是使用提示符:
prompt Arg 1 is &1
或者您可以从双重中选择值,这有点麻烦,或者在dbms_output
周围快速匿名阻止 - 但是对于这种快速检查,prompt
应该没问题。如果你只是在寻找替代值,你可以set verify on
,这是默认值,所以你的脚本可能暂时关闭它。
我似乎能够获得这种效果的唯一方法是,如果我在被调用脚本中有set define off
(或scan off
旧语法),那么它会尝试放置文字字符串{{1变量(显然不适合)而不是它代表的值。据推测,从问题的第二部分来看,你看不出那里放的是什么?
无论如何......如果这不是问题 - 而且如果它被隔离调用似乎不太可能 - 那么我想知道它是否是一个字符集问题,但这听起来也不对。而且我也想知道为什么你强迫它成为一个数值,然后将它作为一个字符串传递,这与问题无关。也许添加更多的SQl脚本可能会有所启发 - 至少从顶部到发生错误的位置。