简体   繁体   English

从shell传递到sqlplus时可变长度的变化

[英]Change in variable lengths while passing from shell to sqlplus

While passing 1 character variables from sqlplus to shell, I find this annoying anomaly. 在将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'

Under EV_DBUPGRADE.sql, I find this error while using the variable vType: 在EV_DBUPGRADE.sql下,我在使用变量vType时发现此错误:

vOption        varchar2(1)  := UPPER('&1');

I get this annoying error that complains of buffer length 我得到这个令人讨厌的错误,抱怨缓冲区长度

declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 7

the error doesn't happen if the varchar2(10) is used. 如果使用varchar2(10),则不会发生错误。 But, I don't want to change it in a million different places. 但是,我不想在百万个不同的地方改变它。 Is there anyway to restrict it? 反正有限制吗? And can anyone please tell me how to print debug messages in sqlplus outside of the BEGIN? 任何人都可以告诉我如何在BEGIN之外的sqlplus中打印调试消息?

I'm not sure exactly what is going on here, but the shell is doing something to your shell variable. 我不确定这里到底发生了什么,但shell正在为你的shell变量做些什么。

I was able to duplicate your error in ksh ("testme.ksh") 我能够在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

The SQL script ("test.sql"): SQL脚本(“test.sql”):

declare
   vOption varchar2(1) := UPPER('&1');
begin
   dbms_output.put_line('Test: ' || vOption);
end;
/

The output: 输出:

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

I'm not sure why this works, but I was able to work around it by passing the shell variable directly to the SQL script execution and bypassing the "define" statement: 我不确定为什么会这样,但我能够通过将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

The output: 输出:

Connected. old 2: vOption varchar2(1) := UPPER('&1'); new 2: vOption varchar2(1)
:= UPPER('1'); PL/SQL procedure successfully completed.

Well, seems rgettman has the actual answer, but I'll leave this here for the bit about prompt ... 好吧,似乎rgettman有实际的答案,但我会留下这里有关prompt ......


The quick version for adding debugs is to use prompt: 添加调试的快速版本是使用提示:

prompt Arg 1 is &1

or you could select the value from dual, which is a bit messier, or have a quick anonymous block around a dbms_output - but for this kind of quick check a prompt ought to be fine. 或者你可以选择dual的值,这有点麻烦,或者在dbms_output周围有一个快速的匿名块 - 但是对于这种快速检查, prompt应该没问题。 If you're only looking for substitution values you can set verify on , which is the default so your script is probably turning it off at the moment. 如果您只是在查找替换值,则可以set verify on ,这是默认值,因此您的脚本可能暂时将其关闭。

The only way I can seem to get that effect is if I have a set define off (or scan off in old syntax) in the called script, so it tries to put the literal string &1 into the variable (which obviously won't fit) instead of the value it represents. 我似乎能够获得这种效果的唯一方法是,如果我在被调用的脚本中有一个set define off (或者在旧语法中scan off ),那么它会尝试将文字字符串&1放入变量中(这显然不适合而不是它代表的价值。 Presumably, from the second part of the question, you can't see what's being put in there? 据推测,从问题的第二部分来看,你看不出那里放的是什么?

Anyway... if that isn't the problem - and it seems unlikely if it works called in isolation - then I'd wondered if it was a character set issue, but that doesn't sound right either. 无论如何......如果那不是问题 - 而且如果它被隔离调用似乎不太可能 - 那么我想知道它是否是一个字符集问题,但这听起来也不对。 And I also wondered why you're forcing it to be a numeric value and then passing it as a string, which isn't really relevant to the problem. 而且我也想知道为什么你强迫它成为一个数值,然后将它作为一个字符串传递,这与问题无关。 Perhaps adding more of the SQl script might shed some light - at least from the top to where the error is occurring. 也许添加更多的SQl脚本可能会有一些亮点 - 至少从顶部到发生错误的地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM