私は次のコードブロックを書きました。
#!/bin/bash
TABLE_NAME="${1}"
COL_NAME="${2}"
FIELD_VALUES_1SQ_FUNC()
{
FIELD_VALUES_1SQS=`sqlplus -s sab/admin@TERM << EOF
SET FEEDBACK OFF;
SET HEADING OFF;
Select TESTING.FIELD_VALUES_TEMP_1SQ.NEXTVAL from dual;
exit;
EOF`
FIELD_VALUES_1SQ=`echo ${FIELD_VALUES_1SQS} | tr -d ' '`
}
RT_SEQ_CHECK_FUNC()
{
RT_SEQ_CHECKS=`sqlplus -s sab/admin@TERM << EOF
SET FEEDBACK OFF;
SET HEADING OFF;
Select * from TESTING.FIELD_VALUES where FIELD_ROW_ID='${1}' and TF_ID='${2}';
exit;
EOF`
RT_SEQ_CHECK=`echo ${RT_SEQ_CHECKS} | tr -d ' '`
}
RT_FIELD_IDS_FUNC()
{
RT_FIELD_IDS=`sqlplus -s sab/admin@TERM << EOF
SET HEADING OFF;
SET FEEDBACK OFF;
select max(TF_ID) from TESTING.TABLE_FIELD where field_id in(select field_id from TESTING.FIELD_DOMAIN where name='${2}') and table_id in (select table_id from TESTING.TABLE where name='${1}');
EXIT;
EOF`
RT_FIELD_ID=`echo ${RT_FIELD_IDS} | tr -d ' '`
}
FIELD_VALUES_1SQ_FUNC
RT_FIELD_IDS_FUNC ${TABLE_NAME} ${COL_NAME}
RT_SEQ_CHECK_FUNC ${FIELD_VALUES_1SQ} ${RT_FIELD_ID}
if [ -z "${RT_SEQ_CHECK}" ]
then
echo "Sequence values doesn't exist |--${RT_SEQ_CHECK}--|"
else
echo "SEQUNCE VAlue exists |--${RT_SEQ_CHECK}--|"
fi
echo "TF_ID=${FIELD_VALUES_1SQ}"
echo "FIELD_ROW_ID=${RT_FIELD_ID}"
exit $?
FIELD_VALUES_1SQ_FUNC
私のスクリプトは最初にシリアル番号を生成する関数を呼び出します。
第二に、RT_FIELD_IDS_FUNC ${TABLE_NAME} ${COL_NAME}
私が呼ぶとき、ある程度の価値を得る。
第三に、RT_SEQ_CHECK_FUNC ${FIELD_VALUES_1SQ} ${RT_FIELD_ID}
その値がデータベースに存在することを確認するために関数を呼び出します。値が存在する場合は、FIELD_VALUES_1SQ_FUNC()
再度呼び出して新しいシーケンス値を生成し、選択したRT_SEQ_CHECK_FUNC ${FIELD_VALUES_1SQ} ${RT_FIELD_ID}
値が関数に見つからない限り、関数を使用して確認する必要があります。FIELD_VALUES_1SQ_FUNC()
これを達成する方法についてのアイデアはありますか?
答え1
あなたが探しているものをwhile
ループと呼びます。次の簡単な例を考えてみましょう。
n=0
while [ $n -lt 5 ]; do
echo Not done yet
n=$(($n+1))
done
while ループは 2 つのタスクを実行し、プログラマが 3 番目のタスクを実行する必要があることを意味します。
- whileループテスト条件:
n
5未満? 条件が真の場合、次のようになります。
- ループ本体は
while
一度実行されます。 - ステップ1に戻って
while
条件を再テストしてください。
- ループ本体は
条件が true でない場合、ループは終了し、スクリプトはdone
loop キーワードの後に続く文を実行し続けます。
第三に、プログラマの責任は、ループ本文内で条件式の状態を変更または変更できるいくつかのタスクを実行することです。上記の簡単な例では、対応するステップはステートメントn = $(($n+1))
です。これがなければ、条件は最初はtrueであり、絶対に変更されないため、ループは無限になります。その行をコメントアウトした状態でスクリプトを実行し、何が起こるかを見てください。次にを押しますCtrlC。
この例を特定の問題に合わせて調整するには、[ -z "${RT_SEQ_CHECK}" ]
テストwhile
を無効にする必要があると思います。私の言葉は、[ -z "${RT_SEQ_CHECK}" ]
trueの場合長さが0であることを意味し${RT_SEQ_CHECK}
、これがまさにあなたが望むものです。止めるリング。幸い、このオプションと正反対のオプションがtest
あります。-n
-z
したがって、広く言えば、while
ループはおおよそ次のようになります。
FIELD_VALUES_1SQ_FUNC
RT_FIELD_IDS_FUNC ${TABLE_NAME} ${COL_NAME}
RT_SEQ_CHECK_FUNC ${FIELD_VALUES_1SQ} ${RT_FIELD_ID}
while [ -n "${RT_SEQ_CHECK}" ]; do
FIELD_VALUES_1SQ_FUNC
RT_FIELD_IDS_FUNC ${TABLE_NAME} ${COL_NAME}
RT_SEQ_CHECK_FUNC ${FIELD_VALUES_1SQ} ${RT_FIELD_ID}
done
最後に、あなたのコード構造について建設的な意見を聞きたいです。グローバル変数を使用して関数から値を返し、コード本体でこれらのグローバル変数を参照する傾向があります。これにより、コードを読み取って追跡するのが困難になる可能性があります。このスタイルでコーディングする代わりに:
STEP1() {
DATE=$(date)
}
STEP2() {
echo "today is $DATE"
}
STEP1
STEP2
この試み:
STEP1() {
date
}
STEP2() {
echo "today is $1"
}
DATE="$(STEP1)"
STEP2 "$DATE"
同様に、コードを適用すると、次のような結果が得られます。
FIELD_VALUES_1SQ_FUNC()
{
sqlplus -s sab/admin@TERM << EOF | tr -d ' '
SET FEEDBACK OFF;
SET HEADING OFF;
Select TESTING.FIELD_VALUES_TEMP_1SQ.NEXTVAL from dual;
exit;
EOF
}
RT_SEQ_CHECK_FUNC()
{
sqlplus -s sab/admin@TERM << EOF | tr -d ' '
SET FEEDBACK OFF;
SET HEADING OFF;
Select * from TESTING.FIELD_VALUES where FIELD_ROW_ID='${1}'
and TF_ID='${2}';
exit;
EOF
}
RT_FIELD_IDS_FUNC()
{
sqlplus -s sab/admin@TERM << EOF | tr -d ' '
SET HEADING OFF;
SET FEEDBACK OFF;
select max(TF_ID) from TESTING.TABLE_FIELD
where field_id in (select field_id from TESTING.FIELD_DOMAIN where name='${2}')
and table_id in (select table_id from TESTING.TABLE where name='${1}');
EXIT;
EOF
}
FIELD_VALUES_1SQ="$(FIELD_VALUES_1SQ_FUNC)"
RT_FIELD_ID="$(RT_FIELD_IDS_FUNC ${TABLE_NAME} ${COL_NAME})"
RT_SEQ_CHECK="$(RT_SEQ_CHECK_FUNC ${FIELD_VALUES_1SQ} ${RT_FIELD_ID})"