Linux

迭代 if else 語句直到條件成功

  • July 10, 2019

我寫了下面的程式碼塊

#!/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()值。

關於如何實現這一點的任何想法!

您要查找的內容稱為while循環。考慮這個簡單的例子:

n=0
while [ $n -lt 5 ]; do
 echo Not done yet
 n=$(($n+1))
done

while 循環做兩件事,暗示程序員必須做第三件事。

  1. while 循環測試條件:n小於 5?
  2. 如果條件為真,則:
  • while循環體執行一次
  • 循環while返回步驟 1 並再次測試條件

如果條件不成立,則循環終止,腳本繼續執行done循環關鍵字後面的語句。

第三件事,程序員的責任,是在循環體內做一些事情,將(或可能)改變條件表達式的狀態。在上面的簡單範例中,該步驟就是n = $(($n+1))語句。沒有這個,循環將變得無限,因為條件最初為真並且永遠不會改變。嘗試在註釋掉該行的情況下執行腳本,看看會發生什麼。然後按Ctrl``C

要針對您的特定問題定制此範例,我認為您需要[ -z "${RT_SEQ_CHECK}" ]針對您的while情況否定測試。我的意思是什麼時候[ -z "${RT_SEQ_CHECK}" ]是真的,這意味著${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})"

引用自:https://unix.stackexchange.com/questions/529262