NULL brrrr….

By | 28 באוקטובר 2010

שדה המכיל ערכי NULL יכול להיות עניין מבלבל. באופן כללי אני מעדיף ששדות בטבלאות הפקט והמימד שלי לא יכילו לעולם NULL. אני משתדל להסיר את אפשרות ה- NULL עוד בשלב בניית הטבלה כדי להבטיח שלא תוכל להכיל NULL. במקום NULL אני מגדיר בתהליך ה- ETL ערך אשר יחליף את ה- NULL במשהו שיסמל "אינו מוגדר". למשל בשדה מספר לקוח, במידה וישנם מספרי לקוח חסרים, אשים מספר שלילי כלשהו במקום NULL (בהנחה שלא יכול להיות לקוח אמיתי עם מספר שלילי. ברם, לפעמים אין ברירה אלא להשאיר NULL. למשל אם המערכת כוללת חישוב ממוצע הכנסות לפי מספר לקוח, הכנסת מספר לקוח במקום NULL תשבש את הממוצע.

העניין מסתבך כאשר מספר הלקוח הינו מידע שיכול להגיע מאוחר (Late arrival attribute value). במצב זה יש לעדכן את ה- NULL לערך אמיתי לאחר שהרשומה כבר נמצאת במימד.

נגדיר טבלה עם שני שדות: שדה A עם ערכים ושדה B עם NULL. לאחר מכן ננסה לעדכן את שדה B באמצעות Merge.

— בניית הטבלא

create
table t1
(a int, b int)

— הכנסת ערכים

insert t1
(a) values (1);

insert t1
(a) values (2);

— Update the NULL into the late arrival value B

merge t1 as matara

using (select 1 as a, 2 as b)
as makor

on makor.a=matara.a

when
matched
and makor.b<>matara.B then

update
set b=makor.b;

למצער, תוצאות ה- Merge הינן (0 row(s) affected). כלומר, העדכון לא הצליח.

דוגמה נוספת:

select

case

when 1<>NULL
then
'1 <> NULL'

else
'I do not know if 1 = NULL'

end
as test

תוצאת השאילתא הינה: I do not know if 1 = NULL

לנו, כבני אדם, די ברור ש- NULL אינו שווה 1. אבל SQL Server מתייחס אל NULL כאל לא מוגדר. כיוון שכך הוא למעשה אומר לנו, איני יודע אם "לא מוגדר" שווה 1 או לא.

לפיכך, גם פעולת ה- Merge לא ביצעה עדכון לרשומה. SQL Server לא נתן ערך TRUE לביטוי makor.b<>matara.B כיוון ש- Matara.B הוא NULL.

כדי למנוע בעיה זו (אשר גזלה ממני מספר שעות) יש לכתוב את ה- Merge מחדש כך:

merge t1 as matara

using (select 1 as a, 2 as b)
as makor

on makor.a=matara.a

when
matched
and makor.b<>
isnull(matara.B,-999)
then

update
set b=makor.b;

בהנחה כמובן שמספר לקוח אינו יכול להיות בשום מקרה -999 .

Share

כתיבת תגובה

האימייל לא יוצג באתר.