מדריך T-SQL: הגדרה ואתחול משתנים



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


מה זה משתנים?

משתנים (variables), הן אבני הבניין הבסיסיות ביותר בכל שפת תכנות. כשאנחנו כותבים תוכנית אנחנו צריכים לעבוד עם מידע: שמות, תאריכים, מספרים, ערכים בוליאנים (True/False) וכו'. כדי לעבוד עם כל המידע הזה אנחנו צריכים לאחסן אותו בצורה כלשהי כדי שנוכל להתייחס אליו או לעשות עליו מניפולציות בצורה נוחה. משתנים הם כמו מיכלי אחסון קטנים שמאפשרים לנו לעשות בדיוק את זה: ע"י הגדרת משתנה, המחשב מקצה מקום בזיכרון לטובת המידע שלנו וכל מה שנשאר לנו לעשות הוא להגיד לו איך לקרוא למקום הזה ומה אנחנו רוצים לשמור בפנים. לאחר מכן, בכל פעם שנרצה להתייחס לאותה פיסת מידע, פשוט נקרא למשתנה שלנו בעזרת השם שהוגדר.


בשפת ה-T-SQL אנחנו חייבים להגדיר מהו סוג המשתנה מאחר ומשתנים ב-SQL Server מסוגלים להכיל ערכים מסוג אחד ספציפי. אם ציינתי שמשתנים מתפקדים כמו מיכלים אז התכונה הזאת מזכירה מיכלי מחזור, כאשר כל מיכל יכול לקבל רק פסולת מסוג מסויים (עכשיו אתם מבינים למה בחרתי את התמונה המשונה הזאת בראש הפוסט). משתנים ב-SQL Server גם אינם יכולים להכיל יותר מערך אחד בכל זמן נתון (למעט משתנים מסוג טבלה שעליהם אדבר בהמשך). במידה ונכניס ערך למשתנה שכבר מכיל ערך אחר, הערך החדש "ידרוס" את הקודם וכך כל משתנה מכיל תמיד את הערך האחרון שהוזן לתוכו.


הגדרת משתנה


כדי להגדיר משתנה חדש אנחנו צריכים להשתמש במילה Declare ("הגדר" באנגלית), להגדיר את שם המשתנה שלנו ואז את סוג הערכים (Data Type) שהמשתנה הזה יהיה מסוגל להכיל. חשוב: שם משתנה תמיד יתחיל עם הסימן "@".


במקרה הזה הגדרנו משתנה מסוג int, מה שאומר שהמשתנה someVar מסוגל לקבל ערכים מספריים שלמים בלבד. ניסיון להכניס לתוכו מחרוזת יסתיים בהודעת שגיאה. ניסיון להכניס לתוכו מספר המכיל ספרות אחרי הנקודה העשרונית יצליח אך SQL Server יעגל אותו לפני שיאחסן את הערך בתוך המשתנה. כמה הערות נוספות:


  • שורות הקוד האלה נקראות Code Block. נהוג להתחיל בלוק במילה BEGIN ולסיים אותו במילה END.

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

  • ניתן לסיים כל הצהרה (Statement) עם הסימן נקודה-פסיק ( ; ). זה לא נותן שום דבר אבל זה נפוץ במערכות אחרות (למשל אורקל) ולמעשה גם הסקריפטים באתר הרשמי של מיקרוסופט נכתבים ככה.

  • כמו ב-SQL, גם ב-T-SQL נהוג לרשום מילים שמורות באותיות גדולות (אבל הקוד יעבוד באותה אופן גם אם לא תקפידו על זה).

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

אתחול משתנים

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


אתחול בערך סטטי

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

המשתנה someVar מכיל עכשיו את המספר 50. שימו לב שהסימן '=' לא מסמל כאן השוואה אלא הצבה. אנחנו מציבים את המספר 50 בתוך המשתנה. הבלוקים שאנחנו רואים כאן נקראים בלוקים אנונימיים מפני שהם רצים פעם אחת ולא נשמרים בשום מקום. זה אומר שהמשתנה someVar לא באמת מאוחסן בשום מקום ורק תופס מקום זמני בזיכרון בעת ההרצה בלבד. אם ננסה להריץ רק את שורה 3 (שורת האתחול) נקבל שגיאה מפני שהשרת לא יזהה את שם המשתנה. כל עוד משתמשים בבלוקים אנונימיים יש להגדיר את המשתנים כל פעם מחדש. החל מגרסת 2010 של SQL Server ניתן לבצע את שתי הפעולות בצורה מקוצרת באופן הבא:


אתחול בערך דינאמי

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

חשוב להבין שמדובר כאן ב-SELECT של הצבה ולא הצגה – שום נתון לא יוצג לנו כשנריץ את הקוד הזה. אבל התוצאה של השאילתה, במקרה הזה – השם של מכונית מספר 1 – תאוחסן בתוך המשתנה. אפשר גם לשלב את שתי הצורות ולהשתמש ב SET כדי להזין משתנה בתוצאה של תת שאילתה:

בשתי הדוגמאות האחרונות ראינו הצבת תוצאה של שאילתה בתוך משתנה ובכל אחת מהן ביצענו וידוא, באמצעות תנאי WHERE, שהשאילתה מחזירה ערך אחד בלבד. זאת נחשבת לכתיבה נכונה מפני שמשתנים יכולים להכיל ערך אחד בלבד. מה היה קורה אם היינו מספקים תנאי שמחזיר יותר מערך אחד? או מריצים את השאילתה ללא WHERE בכלל? בניגוד למצופה (או למקובל במערכות אחרות) SQL Server לא יחזיר שגיאה אלא יכניס את כל הערכים בזה אחר זה לתוך המשתנה, כאשר כל ערך "דורס" את זה שקדם לו. בסופה של ההרצה יכיל המשתנה את הערך האחרון מתוך סט הערכים שהתקבל באותה ריצה.


ניתן גם להשתמש ב SET כדי להכניס למשתנה תוצאה של חישוב או אפילו פלט של פונקציה:

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

© כל הזכויות שמורות לאלעד פלג הדרכות 2020