web-dev-qa-db-ja.com

LNNVLの正当化

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);
12
Leigh Riffel

これは 奇妙な履歴 -を持つ奇妙な関数ですが、 nvl2 が奇妙です。 lnnvlは基本的にis not true演算子です-nvl2のようにうまく利用できることは間違いありませんが、使用するたびに関数を調べて、その機能を正確に思い出させる必要がある場合は、 nvl式に加えて、coalescedecodenullifcaseを使用する方が直感的であるかどうか疑問に思われる

言い換えると、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).
5
Kerri Shotts