LNNVL Gerekçesi


12

LNNVL, FALSE veya UNKNOWN olarak değerlendirilen koşullar için TRUE değerini döndüren ve TRUE olarak değerlendirilen koşullar için FALSE değerini döndüren işlevde yerleşik bir köledir . Sorum şu: NULL değerlerle uğraşmak yerine gerçek durumun tersini döndürmenin faydası ne olacak?

Örneğin, nulls içerebilecek StartCommission ve CurrentCommission sütunlarına sahip bir Emp tablonuz olduğunu varsayalım. Aşağıdakiler yalnızca null değeri olmayan satırları döndürür:

SELECT * FROM Emp WHERE StartCommission = CurrentCommission;

Her iki komisyonun da boş olduğu satırları dahil etmek istiyorsanız, şöyle bir şey yapabilirsiniz:

SELECT * FROM Emp WHERE StartCommission = CurrentCommission 
OR StartCommission IS NULL OR CurrentCommission IS NULL;

Bu sözdizimini kısaltmak için bir işlev varmış gibi görünebilir, ancak LNNVL kullanmak eşit olmayan tüm kayıtları ve boş olan tüm kayıtları döndürür.

SELECT * FROM Emp WHERE LNNVL(StartCommission = CurrentCommission);

Buna NOT DEĞİL eklenirse yalnızca boş olmayan satırlar döndürülür. Bana öyle geliyor ki, bu durum için istenen işlevsellik gerçek koşulları doğru, yanlış koşulları yanlış tutmak ve bilinmeyen koşulların doğru olduğunu değerlendirmek olacaktır. Burada gerçekten düşük kullanımlı bir vaka mı oluşturdum? Bilinmeyeni doğruya, doğruyı yanlışa ve yanlışı doğruya çevirmek gerçekten daha olası mı?

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);

Bugün LNNVL ile tanıştım ve bu gerçeği de bulmaya ya da anlamaya çalışıyorum "gerçeğin tersini döndürmenin yararı ne olurdu". Ancak, LNNVL'yi örneklemek için kullandığınız deyim eşit olmayan bir işleci kullanmalıdır: SEL WAT * FROM Emp WHERE LNNVL (StartCommission <> CurrentCommission); böylece ORs kullanan ifadeyle aynı sonucu döndürür. Başka bir deyişle, bir koşul kullanıyor ve NULL değerine sahip satırları da eklemek istiyorsak, durumumuzun olumsuzluğunu LNNVL'ye geçirmemiz gerekir.
Sadece Siz

Başka bir basit örnek. Yalnızca% 20'den daha az komisyon alan çalışanlar: SELECT * FROM çalışanlardan WHERE komisyon_pct <.2; Hiçbir komisyon almayan çalışanları da dahil etmek için: SELECT * LROMNNVL NEREDEN çalışanlardan (komisyon_pct> = .2);
Sadece Siz

@OnlyYou - Doğru, LNNVL'nin aynı şekilde çalışmasını sağlamak için koşulun <> olması gerekir. = Bıraktım çünkü fonksiyon = işaretiyle aynı sonuçları döndürürse daha anlamlı olur. Temelde fonksiyon iki eylem gerçekleştirir 1. Boş dahil, 2. Boole geçişi. İlki mantıklı, daha sonra istenen durumun tersini gerektiren şeyleri karıştırıyor gibi görünüyor. yani = <> gerektirir, <gerektirir> = vb.
Leigh Riffel

Yanıtlar:


6

Tuhaf bir geçmişi olan garip bir işlevdir - ama nvl2 gariptir . lnnvltemelde bir is not trueoperatördür - şüphesiz kutu gibi iyi bir şekilde kullanılabilir nvl2. nvl, coalesce, decodeve nullifbirlikte casedaha sezgisel olan, ifadeler


NVL2'yi garip bulmuyorum, ama sonra çok kullanıyorum ve hiç LNNVL kullanmadım.
Leigh Riffel

@Leigh - Sanırım tuhaf olmamak için yeterince sık kullanmanız gerekiyor :) Hiç nullifsıfır kullanma '= null yapmak için büyük bir yardımcı olabileceğini anlayana kadar hiç kullanmadım . Gerçekten nvl2'yi (a, c, b) kod çözme işleminden (a, null, b, c) çok daha iyi buluyor musunuz?
Jack diyor ki topanswers.xyz

4

Bu şekilde, bir yıl önce DBA ve PL / SQL Programcısı olduğumda LNNVL'yi henüz kullanmadım. Ben zaman zaman NVL2 kullandım (ve her zaman hangi tarafın doğru ve hangi tarafın olmadığını aramak zorunda kaldım). Bu noktada, okunabilirlik açısından NVL, DECODE, CASE vb.

Alternatif olarak, Oracle'ın NULL'ları ve aritmetiği nasıl ele aldığı konusunda iyi bir ele sahip olduğu varsayılarak, ancak bu noktada, orijinal sorgunuzu okunabilirlik için de kullanabileceği varsayılabilir (ve yürütme planı da daha sert bir isabet alabilir):

/* 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).

Bunu mu demek istediniz StartCommission<>CurrentCommission OR StartCommission + CurrentCommission IS NULL?
Jack diyor ki topanswers.xyz

@JackPDouglas - = anlamlıdır.
Leigh Riffel

İlginç varyasyon. Sonuçlarına katılıyorum.
Leigh Riffel

@Leigh - Anlıyorum, istediğiniz işleve alternatif değil, alternatif lnnvl.
Jack diyor ki topanswers.xyz

@JackPDouglas - Anlıyorum ve Kerri'nin amaçladığı şey bu.
Leigh Riffel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.