הבלוג של גרי רשף

01/12/2011

שימוש בערכי ברירות לפרמטרים בפרוצדורות ופונקציות

Filed under: Uncategorized — גרי רשף @ 21:38

בפרוצדורות ופונקציות ניתן לתת לפרמטרים שהן מקבלות ערכי ברירת מחדל, ואזי ניתן להפעילן מבלי לציין במפורש את ערך הפרמטר; כמובן בהנחה שאנחנו מעוניינים שהוא יקבל את ערך ברירת המחדל ולא אחר.
זה הופך אותן לנוחות לשימוש, למשל- בעבר הצגתי פרוצדורה להעתקת נתוני טבלה מהייצור לפיתוח. בגרסה בה אני משתמש במקום העבודה ניתן להפעיל את הפרוצדורה עם שם הטבלה בלבד, והיא "תדע" לפנות לשרת הייצור המצויין כברירת מחדל. אם ארצה להעתיק משרת אחר- אציין אותו במפורש בהפעלה. באופן דומה- אני מניח ששם הדטבייס בשרת ממנו מעתיקים הוא כשם הדטבייס בו אני נמצא (פונקציית המערכת ()DB_Name), אלא אם כן נאמר במפורש אחרת.
זה נוח גם למקרה ששידרגנו פרוצדורה קיימת, ועבור מקרים מיוחדים הוספנו לה פרמטרים מתאימים. כעת נצטרך לכאורה לחפש בכל התהליכים היכן אנחנו משתמשים בפרוצדורה הזו ולהוסיף לפקודות ההפעלה שלה את הפרמטרים החדשים, אבל אם נשכיל לתת להם ערכי ברירת מחדל למקרים שאינם בגדר "המקרים המיוחדים" הנ"ל- נחסוך הרבה כאב ראש.
לדוגמה- הייתה לנו פרוצדורה לחישוב חֲזקות – מקבלת מספר ומעלה אותו בריבוע:

Use tempdb;
Go

If Object_Id('P_Hezka','P') Is Not Null Drop Proc P_Hezka;
Go

Create Proc P_Hezka @Basis Int As
Declare @Hezka Int;
Set     @Hezka=@Basis*@Basis;
Select  @Hezka;
Go

Exec P_Hezka 5;
Go

clip_image002

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

If Object_Id('P_Hezka','P') Is Not Null Drop Proc P_Hezka;
Go

Create Proc P_Hezka @Basis Int,
                    @Maarih Int=2 As
Declare @Hezka Int;
Set     @Hezka=Power(@Basis,@Maarih);
Select  @Hezka;
Go

Exec P_Hezka 5;
Exec P_Hezka 5,3;
Go

clip_image004

מה עם פונקציות? פה יש בעייה קטנה: נתחיל מפונקציה פשוטה שמעלה בריבוע:

If Object_Id('F_Hezka','Fn') Is Not Null Drop Function F_Hezka;
Go

Create Function dbo.F_Hezka(@Basis Int)
                            Returns Int As
Begin
Declare @Hezka Int;
Set     @Hezka=@Basis*@Basis;
Return(@Hezka);
End;
Go

Select dbo.F_Hezka(5);
Go

clip_image006

כעת אם נרצה להוסיף להוסיף לה פרמטר אופציונאלי למעריך של החזקה:

If Object_Id('F_Hezka','Fn') Is Not Null Drop Function F_Hezka;
Go

Create Function dbo.F_Hezka(@Basis Int,
                            @Maarih Int=2)
Returns Int As
Begin
Declare @Hezka Int;
Set     @Hezka=Power(@Basis,@Maarih);
Return(@Hezka);
End;
Go

Select dbo.F_Hezka(5,Default);
Select dbo.F_Hezka(5,3);
Go

clip_image008

כפי שניתן לראות- הפעם אנחנו נאלצים לכתוב Default במקום הפרמטר השני, נכון שאנחנו פטורים מלציין אותו במפורש, אבל עדיין נצטרך לתקן את הקודים הקיימים במערכת כי לא ניתן להפעיל את הפונקציה כבעבר..

פתרון אפשרי לבעייה שאינו מושלם ואינו הכי אלגנטי יכול להיות יצירה של פונקציה חדשה שתטפל בכל המקרים, ושינוי הפונקציה הישנה כך שתפעיל את החדשה עם ערך ה-default:

If Object_Id('F_HezkaNew','Fn') Is Not Null Drop Function F_HezkaNew;
Go

Create Function dbo.F_HezkaNew(@Basis Int,
                               @Maarih Int=2)
                               Returns Int As
Begin
Declare @Hezka Int;
Set     @Hezka=Power(@Basis,@Maarih);
Return(@Hezka);
End;
Go

If Object_Id('F_Hezka','Fn') Is Not Null Drop Function F_Hezka;
Go

Create Function dbo.F_Hezka(@Basis Int)
                            Returns Int As
Begin
Return dbo.F_HezkaNew(@Basis,Default);
End;
Go

Select dbo.F_Hezka(5);
Select dbo.F_HezkaNew(5,Default);
Select dbo.F_HezkaNew(5,3);
Go

clip_image010

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

נו טוב- מה הועילו חכמים בתקנתם? כעת יש לנו שתי פונקציות- אחת להעלאה בריבוע והשניה למקרים אחרים..

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

להגיב »

עדיין אין תגובות.

RSS feed for comments on this post. TrackBack URI

כתיבת תגובה

יצירה של אתר חינמי או בלוג ב־WordPress.com.