雖然 CASE 結(jié)構(gòu)基本上沒有給出任何新的語義,但它們的確接受一種更簡潔的表示法,并且相對于 IF 結(jié)構(gòu)表示法而言消除了一些重復(fù)??聪旅娴呐卸ū淼膱?zhí)行情況,是依據(jù)特殊表達式的值來決定執(zhí)行情況。程序段…
case nwhen 1 then Action1;when 2 then Action2;when 3 then Action3;else ActionOther;
end case;
…和…
ifn = 1 then Action1;elsif n = 2 then Action2;
elsif n = 3 then Action2;
else ActionOther;
end if;
… 在語義是幾乎是相同的。但編碼最佳實踐專家通常會推薦 CASE 表示法,因為它更直接地反映了概念。通過將判定表達式 n 放在開始位置并且只寫一次,程序員的目的變得更清晰了。這對校對員和編譯器都很有意義,因此為生成高效代碼提供了更好的信息。比如說,編譯器可以立即知道判定表達式只需校核一次。而 IF 表示法在每個情況段重復(fù)決策表達式,所以出現(xiàn)輸入錯誤的風(fēng)險更大,并且這種錯誤很難找出。
此外,CASE 表示法可以明確指出只有已編寫代碼的情況才需要處理(參見以下關(guān)于 case_not_found 異常的討論)。
大多數(shù)編程語言都提供 CASE 結(jié)構(gòu)。Oracle9i 將它們引入了 PL/SQL(和 SQL)中。
CASE 表達式CASE 表達式選擇一種結(jié)果并將之返回。CASE 表達式使用一個選擇器來選擇結(jié)果,選擇器是一個表達式,它的值用來在幾個選項中作出選擇。分析一下兩個語義上幾乎相同的程序段
text := case nwhen 1 then one when 2 then two when 3 then three else otherend case;
…和
ifn = 1 then text := one; elsif n = 2 then text := two; elsif n = 3 then text := three;else text := other;end if;
除 CASE 表達式外還可選用 CASE 語句,其中每一個 WHEN 子句都可以作為一個完整的 PL/SQL 程序塊。
Searched CASE 語句和 Searched CASE 表達式對 CASE 語句和 CASE 表達式兩者而言,searched 變量在每一個分支下測試一個任意的布爾表達式,而不是測試一個所有分支下公共的單個表達式的相等性,如下所示
casewhen n = 1 then Action1;
when n = 2 then Action2;
when n = 3 then Action3;
when ( n > 3 and n < 8 ) then Action4through7;
else ActionOther;
end case;
…和…
text := casewhen n = 1 then one when n = 2 then twowhen n = 3 then three when ( n > 3 and n < 8 ) then four_through_seven else otherend;
注意:在使用 CASE 表示法與使用 IF 表示法時一樣,為特定數(shù)值選出的分支一般都依賴于分支編寫的順序。試分析…
casewhen this_patient.pregnant = 'Y' then Action1;when this_patient.unconscious = 'Y' then Action2;when this_patient.age < 5 then Action3;when this_patient.gender = 'F' then Action4;else ActionOther;end case;CASE_NOT_FOUND 異常當(dāng) ELSE 程序段被遺漏時,CASE 結(jié)構(gòu)和相應(yīng)的 IF 結(jié)構(gòu)會有微妙的差別。使用 IF 結(jié)構(gòu)時,如果沒有選擇任何分支,那么就不會有操作。但使用 CASE 結(jié)構(gòu)時,如果沒有選擇任何分支,那么 case_not_found 異常(ORA-06592:在執(zhí)行 CASE 語句時,沒有發(fā)現(xiàn) CASE£?就會觸發(fā),如下所示#133;...
p:=0; q:=0; r:=0;
case
when p = 1 then Action1;
when r = 2 then Action2;
when q > 1 then Action3;
end case;
exception
when case_not_found
then Dbms_Output.Put_Line ( 'Trapped:case_not_found' );