うまく動作するスクリプトがありますTOAD
。
SELECT max (ID)+1 from apps_details;
シェルスクリプトで実行しようとすると、次のエラーが発生します。
DB_CONNECT="XXXXX/XXXXX@XXXXXX"
echo "Inserting the DataBase"
/oravl01/oracle/12.1.0.1/bin/sqlplus -s $DB_CONNECT <<END
set head off
set feedback off
set pagesize 2400
set linesize 2048
ID_VAL=`SELECT max (ID)+1 from apps_details;`
exit
END
/pciuser/tools/jenkins/jenkins/scripts/Jenkins_Internal/Create_Jenkins_Container/InsertToDB.ksh[31]: syntax error at line 1: `(' unexpected
31号線行を参照しますが、ジョブをoravl01
削除すると機能したため、問題が存在しないことがわかります。ID_VAL
正しい構文は何ですか?
答え1
このコマンドは私にとって効果的でした。
DB_CONNECT="XXXXX/XXXXX@XXXXX"
ID_VAL=$(sqlplus -s $DB_CONNECT <<END
set head off
set feedback off
set pagesize 2400
set linesize 2048
SELECT max (ID)+1 from apps_details;
exit;
END
)
echo $ID_VAL
答え2
私の考えでは、最初にコマンドを定義してから実行して出力を保存する方が、よりきれいで簡単なようです。
DB_CONNECT="XXXXX/XXXXX@XXXXXX"
read -r -d '' command <<END
set head off
set feedback off
set pagesize 2400
set linesize 2048
SELECT max (ID)+1 from apps_details;
exit
END
echo "Inserting the DataBase"
ID_VAL=$(/oravl01/oracle/12.1.0.1/bin/sqlplus -s "$DB_CONNECT" <<<"$command")
これにより、出力を変数に簡単に保存し、コマンドをスクリプトフローから切り離すことができ、後で理解し維持するのが簡単になります。
答え3
おおよそ次のようないくつかの選択肢があります。テドンの答え、SQL*Plusの出力をより簡単に処理したいと思います。あなたは努力していますシェル変数としてインポートしますID_VAL
。
既定では、SQL*Plus で実行される SQL ステートメントは、そのデータ・タイプによって幅が異なる列で構成される書式付きレポートを生成します。これは潜在的に望ましくない効果を引き起こす可能性があります。たとえば、指摘した左パディング数コメントから。
デモ:
$ DB_CONNECT="user/password@db"
$ ID_VAL="$(sqlplus -s $DB_CONNECT <<'END'
set feedback off
set head off
set pagesize 0
SELECT 123 FROM DUAL
/
END
)"
$ printf '"%s"\n' "$ID_VAL"
" 123"
$ printf '%s' "$ID_VAL" | od -An -tx1
20 20 20 20 20 20 20 31 32 33
いくつかの選択肢:
数値を選択すると、文字列に変換され、SQL文から切り捨てられます。上記のスクリプトの他のすべては同じままです(
SELECT
テスト目的でダミーステートメントを使用します)。SELECT TRIM(TO_CHAR(123)) FROM DUAL;
dbms_output.put_line
PL/SQLブロックに使用されます。ID_VAL="$(sqlplus -s $DB_CONNECT <<'END' set serveroutput on set feedback off DECLARE myvar NUMBER; BEGIN SELECT 123 INTO myvar FROM DUAL; dbms_output.put_line(myvar); END; / END )"
これは
set serveroutput on
必須です。それ以外の場合、出力は表示されません。
(1)と(2)を組み合わせると、次のような結果が得られます。
$ printf '"%s"\n' "$ID_VAL"
"123"
$ printf '%s' "$ID_VAL" | od -An -tx1
31 32 33
ただし、保持したい空白文字を含む文字列(たとえばfoo
)を選択すると、これらの方法は失敗します。文字列を引用符で囲んで削除するか、次のようにします。
SQL*Plus で出力形式を CSV として指定します。
ID_VAL="$(sqlplus -s -M "CSV ON" $DB_CONNECT <<'END' set feedback off set head off SELECT ' foo ' FROM DUAL; END )" printf '"%s"\n' "$ID_VAL" "" foo ""
数字とは異なり、文字列は二重引用符で囲まれており、少し後処理が必要です。返された値に文字が含まれていないと仮定すると、次を使用して開始文字と終了文字(他のすべての文字は変更されません)を削除する
<newline>
方法があります。sed
"
ID_VAL="$(sqlplus -s -M "CSV ON" $DB_CONNECT <<'END' | sed 's/^"//; s/"$//;'
最良の選択は実際のユースケースによって異なります。