רשומת ברירת מחדל

12/06/2012

תגיות: , ,
אין תגובות

נתקלתי במקרים בהם היה צורך בכתיבת שאילתה שבמקרה בו אין נתונים- תחזיר רשומת ברירת מחדל כלשהי. למשל:
1. מערכת המאפשרת ללקוח לעיין בהזמנות שלו, ואם אין הזמנות- להציע לו פריט להזמנה.
2. דוח שכדי שלא יפול כשאין בו נתונים- מציגים הודעת מערכת מתאימה.
ניתן כמובן לעשות זאת על ידי סקריפט מתאים: לשלוף את הנתונים לטבלה זמנית, לבדוק אם נשלף משהו, אם כן- להציג אותו, ואם לא- להציג את רשומת ברירת המחדל וכו'; אך אנחנו מחפשים דרך לעשות זאת בשליפה אחת.
ניצור קודם כל טבלת נתונים להדגמה:

Use tempdb;

Go

 

If Object_ID('Messages') Is Not Null Drop Table Messages;

Go

 

Select  *

Into    Messages

From    sys.messages;

 

Alter   Table Messages Add Constraint PK_Messages Primary Key Clustered (message_id,language_id);

Go

 

Select  *

From    Messages;

clip_image002

אנחנו מעוניינים לשלוף את כל השורות להן message_id מסויים,

ואם אין- להציג שורה מלאכותית:

Select  1 message_id,

        1033 language_id,

        15 severity,

        0 is_event_logged,

        'My Message' text;

clip_image004

אפשרות אחת היא ליצור Union בין השליפה המבוקשת מהטבלה לבין שליפת הרשומה המלאכותית לה יתווסף תנאי שבשליפה הראשונה אין רשומות,

והאפשרות השניה היותר מתוחכמת היא ליצור Left Join בין הרשומה המלאכותית לשליפה מהטבלה ואז הרשומה המלאכותית תופיע עם Nulls לידה (כשאין רשומות בשליפה מהטבלה) או שתופיע עם כל הרשומות (אם יש) ובשני המקרים נבחר על ידי IsNull את מי מהשניים להציג.

למשל עבור message_id=21 (יש שורות בטבלה):

Select  *

From    Messages

Where   message_id=21

Union All

Select  1 message_id,

        1033 language_id,

        15 severity,

        0 is_event_logged,

        'My Message' text

Where   (Select Top 1 1 From Messages Where message_id=21) Is Null;

 

Select  IsNull(M.message_id,T.message_id) message_id,

        IsNull(M.language_id,T.language_id) language_id,

        IsNull(M.severity,T.severity) severity,

        IsNull(M.is_event_logged,T.is_event_logged) is_event_logged,

        IsNull(M.text,T.text) text

From    (Select 1 message_id,

                1033 language_id,

                15 severity,

                0 is_event_logged,

                'My Message' text) T

Left Join Messages M

        On M.message_id=21;

clip_image006

או עבור message_id=1 (אין שורות מתאימות בטבלה):

clip_image008

ומה ההבדל בביצועים? נבדוק לגבי message_id=21:

clip_image010ההבדל ההבדל שבין שתי פניות לטבלה בשליפה הראשונה לפניה אחת בשליפה השניה- זו בדיוק הסיבה למחיר הכפול של הראשונה, ולכך שמומלץ להשתמש בשניה.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *