1

sqlplus からシェルに 1 文字の変数を渡しているときに、この厄介な異常が見つかりました。

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 でデバッグ メッセージを出力する方法を教えてください。

4

2 に答える 2

2

ここで何が起こっているのか正確にはわかりませんが、シェルはシェル変数に対して何かを行っています。

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

これが機能する理由はわかりませんが、シェル変数を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.
于 2013-02-15T23:58:34.117 に答える
1

さて、rgettmanが実際の答えを持っているようですが、これについては少しここに残しておきますprompt...


デバッグを追加するための簡単なバージョンは、プロンプトを使用することです。

prompt Arg 1 is &1

または、少し面倒なデュアルから値を選択するか、dbms_output-の周りに簡単な匿名ブロックを設定することもできますが、この種のクイックチェックにはprompt問題がないはずです。置換値のみを探している場合はset verify on、これがデフォルトであるため、スクリプトはおそらく現時点でそれをオフにしています。

その効果を得ることができる唯一の方法は、呼び出されたスクリプトにset define off(または古い構文で)ある場合です。そのため、値ではなくリテラル文字列を変数(明らかに適合しません)にscan off入れようとします。&1を表します。おそらく、質問の2番目の部分から、そこに何が入れられているのかわかりませんか?

とにかく...それが問題ではなく、単独で呼び出されて動作する可能性は低いと思われる場合は、文字セットの問題であるかどうか疑問に思いましたが、それも正しく聞こえません。また、なぜそれを数値に強制してから文字列として渡すのか疑問に思いましたが、これは問題とはあまり関係がありません。おそらく、SQlスクリプトをさらに追加すると、少なくともエラーが発生している場所の上部から、ある程度の光が当てられる可能性があります。

于 2013-02-15T23:59:09.323 に答える