none
המרות עם שימוש ב ISNULL RRS feed

  • דיון כללי

  • הבוקר קראו לי לטיפול בתקלה הקשורה בהרצת SP.

    לאחר בדיקה קצרה בשאילתה שלא נגמרת (אורך הקוד) עליתי על התקלה, מדובר במקרה בו השרת מנסה להמיר ערך ל smalldatetime.

    תיקון קליל פתר את העיה אך אני עדיין רוצה להבין את למה זה קורה, אשמח לתשובה.

    הנה סקריפט להמחשת הבעיה (הקשורה כמובן לתאריך 29/2)

    create table dbo.Test(Date1 SMALLDATETIME
    )


    INSERT INTO dbo.Test VALUES('20120227'),('20120228'),('20120229'),('20120301')

     

    SELECT *

    FROM dbo.Test

    DECLARE @a AS VARCHAR(8)

    SET @a = '20120229'


    DECLARE @b AS VARCHAR(8)


    --SET @b = '20120229'


    -- ooops

    select *

    from dbo.Test

    WHERE Date1 >= ISNULL(@a, Date1)

     AND
     
     Date1 <= ISNULL(@b, Date1)


    -- now its ok
    select *

    from dbo.Test

    WHERE Date1 >= ISNULL(@a, Date1)

     AND

     Date1 <= ISNULL(CAST(@b AS SMALLDATETIME), Date1)

    • שינה את הסוג Eran Sharvit יום ראשון 11 מרץ 2012 14:44
    יום שני 27 פברואר 2012 09:51

כל התגובות

  • הי,

    הבעיה שלך היא ב- Declaration של המשתנה B. מחרוזת באורך שמונה לא יכולה להיות ממומרת ל- Datetime במידה ולא ציינתה בפרוש את הפורמט.

    תשנה את הגודל ל- 12 והכל יסתדר.

    מבנה התאריך הדיפולטיבי הוא YYYY-MM-DD.

    ברגע ששינתה את ה- Datatype של עמודה B להיות smalldatetime אז כמובן, גם כן, נפתרה הבעיה.

    בקיצור מכוון שבפילטור חייבת להתבצע המרה לסוג משתנה datetime אז ההגדרה של המחרוזת  בעורך 8 עבור משתנה B הכשילה את ההמרה.

    יום טוב 


    אסף שלם

    יום שני 27 פברואר 2012 10:27
  • אני חייב להודות ששימוש בפונקציה COALESCE שהיא עדיפה על ISNULL גם פותרת את הבעיה.

    select *
    from dbo.Test 
    WHERE Date1 >= COALESCE(@a, Date1)
    AND
    Date1 <= COALESCE(@b, Date1)

    יניב

    יום שני 27 פברואר 2012 11:56
  • היי יניב,

    במה לדעתך COALESCE עדיפה על ISNULL?

    מבחינת ביצועים - ל ISNULL יש יתרון בהרבה מקרים מכיוון שהיא לא מתפרקת פנימית ל CASE מלא כמו COALESCE.


    Ami Levin, SQL Server MVP. CTO, DBSophic LTD. - http://www.dbsophic.com/ --Performance is the most significant driver in maintaining data and service availability.--

    יום שני 27 פברואר 2012 12:51
  • לזכרוני הדברים הם לא שחור לבן ופועלים בצורה הבאה:

    בעקרון ISNULL מתפרק ל IF בעוד COALESCE מתפרק ל CASE, אבל זה לא אומר שאחד עדיף מהשני תמיד

    נדון רגע על המקרה שיש לנו 3 מצבים x,y,z ואנו רוצים לבחור את המתאים. נדבר על השימוש ב IF לעומת CASE. ז"א

    if MyVar = x
    בלוק של X
    elseif MyVar = y
    בלוק של Y
    else ....
    בלוק של אחר

    לעומת

    select case
    x
    בלוק של X
    Y
    בלוק של Y
    ELSE
    בלוק של אחר

    וההסבר:

    הרעיון שהופך את CASE ליעיל הרבה יותר לעיתים (אני מדבר עכשיו ברמת היסוד של פיתוח המחלקה ומה קורה מאחורי הקלעים) זה ש CASE מיישמים למשל על ידי שימוש באוסף של תוצאות אפשריות שמאפשר שימוש בפונקציית HASH (למשל SORTEDLIST או פשוט HASHTABLE שיכיל במקרה שלנו את x,y,z). כאשר מגיעים ל CASE פונקציית ההאש שלנו מאפשרת גישה ישירה לאיבר המתאים באוסף ולכן מציאת האיבר שמחפשים ובחירת מקטע הקוד של ה CASE שירוץ נעשה עם "קפיצה מיידית" לבלוק המתאים. אין נגיעה בכלל בבלוקים האחרים כאילו הם לא קיימים בקוד.

    בניגוד לכך שימוש ב IF למשל ברצף של כמה IF ו IFELSE גורר שהבדיקה נעשית פיזית עבור כל אפשרות בנפרד עד שנמצאה האפשרות המתאימה. כך שאכן נראה שזה פחות יעיל במבט ראשון אבל מצד שני אין צורך באובייקט נוסף של אוסף ואין צורך בפונקציית האש והדברים "קלים" יותר

    אז מתי כל אחד יעיל?

    אם התוצאה תהיה האפשרות הראשונה השימוש ב IF יעיל יותר אבל אם התוצאה תהיה האפשרות המליון האפשרות של CASE הרבה הרבה הרב ה יותר יעילה.


    * כלל אצבע: אישית אני לא בדקתי מאיזה כמות היעילות של CASE עולה על IF אבל בפיתוח אני משתמש בכלל אצבע של אם יש יותר מ 3 אפשרויות או שבעתיד עלולות להיות אפשרויות נוספות אז אני אעדיף CASE אבל אם מדובר ב 2 אפשרויות אז IF ו IFELSE ישמש אותי בדרך כלל

    * הערה: כמובן שכל חברה יכולה לממש את CASE בצורה שונה וזה רק אלגוריתמים בסיסי נפוץ בפיתוח.


    signature

    יום רביעי 29 פברואר 2012 06:46
    מנחה דיון
  • אם לא הובנתי טוב (או ככל הנראה לא הסברתי טוב) אז לאנשי ה DBA יהיה קל להבין מה היא פונקציית האש אם נשווה אותה לאינדקס של טבלה. כמו שבטבלה אנחנו מגדירים אינדקס כך במקרה של CASE אנחנו יכולים להגדיר את האוסף. החיפוש במקום שיעשה בטבלה נעשה באינדקס כמו שהוא נעשה באוסף שלנו במקום בקוד המקורי. יותר מזה פונקציית ההאש מגדירה את הקשר בין המפתח לבין הערך. כך שאם מחפשים ערך מסויים היא כבר מחזיקה אצלה את הקשר (הפונקציה) ולכן מציאת הערך נעשית בצורה מהירה מאוד בסדרי גודל ביחס לבדיקה והשווה של כל אפשרות בנפרד. לכן במקרים של שימוש בערכים רבים / אפשרויות רבות האינדקס או פונקציית האש שלנו הופכת להיות הדרך היעילה ביותר ולכן CASE הוא הפתרון במקרה זה. כאמור זה לא תמיד נכון ולפעמים השימוש ב IF עדיף כפי שהסברתי מעל (או כפי שניסתי להסביר :-)). אני מקווה שזה מבהיר מעט על מה זה פונקציית האש
    יום רביעי 29 פברואר 2012 07:20
    מנחה דיון
  • שלום,

    חברי הקהילה השקיעו מזמנם ונסיונם על מנת לסייע לך למצוא פתרון לבעייתך.

    לכן, אם אחת מן התשובות פתרה או עזרה לפתור את בעייתך, אנא סמן אותה על ידי לחיצה על "סמן כתשובה".

    אם מצאת פתרון אחר, נשמח אם תשתף אותנו על מנת שאחרים אשר מגיעים לפורום יוכלו להעזר בו.

    תודה,

    צוות הפורומים.


    מיקרוסופט מציעה שירות זה ללא תשלום, למטרת סיוע למשתמשים העשרת הידע הקשור בטכנולוגיות ובמוצרים של Microsoft. תוכן זה מתפרסם כפי שהוא והוא אינו מעיד על כל אחריות מצד מיקרוסופט.

    יום ראשון 04 מרץ 2012 15:45
  • היי pituach,

    זכרונך מטעה אותך.

    ISNULL לא מתפרק ל IF.

    IF ב SQL הוא אופרטור זרימה (Flow) ברמת משפט (Statement) ולא ברמת ביטוי (expression).


    Ami Levin, SQL Server MVP. CTO, DBSophic LTD. - http://www.dbsophic.com/ --Performance is the most significant driver in maintaining data and service availability.--

    יום שני 05 מרץ 2012 08:21
  • תודה על התיקון

    * אני לא בטוח שאני מבין כרגע מה ההבדל מבחינה מעשית. אני אשמח לקישור למאמר הנותן יותר אינפורמציה על מאחורי הקלעים (המחלקה שבה מוגדרת המתודה ISNULL אני אבדוק את זה יותר לעומק). או הסבר כללי על ההבדל בין אופרטור זרימה (Flow) ברמת משפט (Statement) ובין ברמת ביטוי (expression) מבחינת אופן העבודה (לא מצאתי כניראה מפני שלא ידעתי מה לחפש בדיוק כרגע).

    אם למשל תהיה צריך לבצע כמה בדיקות בזו אחר זו

    isnull(isnull(isnull....)

    האם מבחינה מעשית דרך העבודה לא תהיה זהה? האם ב אופרטור זרימה (Flow) ברמת משפט (Statement) לא תהיה גישה לכל "בדיקה" בזו לאחר זו בניגוד לעבודה עם ב CASE למשל לפי ההסבר מעל?

    יום שני 05 מרץ 2012 09:44
    מנחה דיון
  • שלום יניב,

    כיוון שלא התקבלה תגובתך לפיתרון שהוצע, סוג האשכול שונה מ"שאלה" ל"דיון".

    במידה ומצאת את אחת מהתשובות מועילות, נשמח לתגובה, על מנת שנוכל לשנות את הסוג בחזרה ולסמן את הפיתרון.

    במידה ומצאת פיתרון בצורה עצמאית, נשמח לשתף בו את שאר חברי הפורום.

    תודה,

    צוות הפורומים.


    מיקרוסופט מציעה שירות זה ללא תשלום, למטרת סיוע למשתמשים העשרת הידע הקשור בטכנולוגיות ובמוצרים של Microsoft. תוכן זה מתפרסם כפי שהוא והוא אינו מעיד על כל אחריות מצד מיקרוסופט.

    יום ראשון 11 מרץ 2012 14:44