LNNVLはOracleの組み込み関数です は、FALSEまたはUNKNOWNと評価される条件に対してTRUEを返し、TRUEと評価される条件に対してFALSEを返します。私の質問は、NULL値を処理するだけでなく、真の条件の反対を返すことの利点は何でしょうか?
たとえば、NULLを含む可能性のあるStartCommission列とCurrentCommission列を含むEmpテーブルがあるとします。次の例では、どちらの値もnullでない行のみを返します。
SELECT * FROM Emp WHERE StartCommission = CurrentCommission;
いずれかの歩合がnullである行を含めたい場合は、次のようにすることができます。
SELECT * FROM Emp WHERE StartCommission = CurrentCommission
OR StartCommission IS NULL OR CurrentCommission IS NULL;
この構文を短くする関数が存在するように見えますが、LNNVLを使用すると、すべての等しくないレコードとすべてのレコードがnullで返されます。
SELECT * FROM Emp WHERE LNNVL(StartCommission = CurrentCommission);
これにNOTを追加すると、nullのない行のみが返されます。この場合の望ましい機能は、true条件をtrue、false条件をfalseに保ち、unknown条件をtrueと評価することです。私は本当に低いユースケースをここで作成しましたか? unknownをtrueに、trueをfalseに、falseをtrueに変えたいと思う可能性は本当に高いですか?
create table emp (StartCommission Number(3,2), CurrentCommission Number(3,2));
insert into emp values (null,null);
insert into emp values (null,.1);
insert into emp values (.2,null);
insert into emp values (.3,.4);
言い換えると、DBAやPL/SQLプログラマーとしての数年間、LNNVLを使用したことは一度もありません。私はときどきNVL2を使用しました(そして常にどちらの側が真でどちらがそうでなかったかを調べなければなりませんでした)。その時点では、読みやすさの観点から、NVL、DECODE、CASEなどを使用する方が良いように見えます。
あるいは、これはOracleがNULLと算術を処理する方法に優れたハンドルを持っていると仮定して機能しますが、この時点で、読みやすさのために元のクエリを使用することもできます(実行プランもより困難になる場合があります)。
/* Return all rows where StartCommission is the same
* as Current Commission, or those rows who have a
* NULL in either (including both)
*/
SELECT *
FROM Emp
WHERE StartCommission = CurrentCommission
OR StartCommission + CurrentCommission IS NULL
-- NULL + NULL, or NULL + Number is always NULL; hence return either
-- those records that are equal, or have a combined total of NULL
-- (either or both fields will be NULL).