Download as pdf or txt
Download as pdf or txt
You are on page 1of 143

Querying Data with sql

server 2016

27740-9287-02
‫תוכן עניינים‬
3 ..................................................................................................................................... ‫מבוא‬
13 ................................................................ sql server managment studio – SSMS ‫עבודה עם‬
15 ........................................................................................................ SELECT ‫ פקודת‬- 1‫פרק‬
20 ................................................................................................... WHERE ‫ משפט ה‬- 2 ‫פרק‬
28 ........................................................................ )Scalar functions( ‫ פונקציות סקלריות‬- 3 ‫פרק‬
41 ......................................................................................... SQL Server Data Types - 4 ‫פרק‬
43 ...............................................................................)JOIN( ‫שילוב מידע ממספר טבלאות‬-5 ‫פרק‬
50 ....................................................................... Group Function And Grouping Sets - 6 ‫פרק‬
56 ................................................................................. )SUBQUERIES( ‫ תתי שאילתות‬- 7 ‫פרק‬
60 ....................................................................................................... SET Operators - 8 ‫פרק‬
63 ................................................................................................. Window Functions - 9 ‫פרק‬
70 .................................................................... Common Table Expressions (CTE) -10 ‫פרק‬
72 ................................................................................................................. Pivoting- 11 ‫פרק‬
75 ......................................................................................................... DML ‫ – פקודות‬12 ‫פרק‬
81 .............................................................. Data Definition Language – DDL ‫ פקודות‬- 13 ‫פרק‬
88 ...................................................................................................................... View -14 ‫פרק‬
90 ....................................................................................................... T-SQL BASIC -15 ‫פרק‬
100 ................................................................................................ Stored procedure -16 ‫פרק‬
108 .............................................................................................................................. ‫נספחים‬
139 ............................................................................................................. SQL ‫תקציר פקודות‬

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 2 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫מבוא‬
‫חוברת זו תקנה לך את הידע והכישורים הטכניים הנדרשים לשם פיתוח קוד בסביבת‬
‫‪.SQL Server‬‬

‫מושגי יסוד‬
‫‪ Database ‬מסד נתונים‬
‫‪ Relational Database ‬מסד נתונים יחסי‬
‫‪ RDBMS ‬מערכת לניהול מסד נתונים יחסי‬
‫‪ ‬שפת ‪SQL‬‬
‫‪ ‬שפת ‪T-SQL‬‬

‫מסד נתונים (‪)Database‬‬


‫אוסף נתונים המאורגנים בצורה שתאפשר חיפוש ושליפה מהירים של המידע‪.‬‬
‫לדוגמה‪ :‬מגירת תיקיות במשרד כוח האדם בארגון מהווה מסד נתונים‪ :‬התיקיות האישיות על העובדים מכילות‬
‫מידע‪ .‬התיקיות מסודרות בסדר אלפאב תי מה שמאפשר חיפוש ושליפה מהירים של הנתונים הנוגעים לעובד‬
‫מסויים‪.‬‬
‫כיום רובם המוחלט של מסדי הנתונים מבוססים על אחסון המידע במסד נתונים ממוחשב‪.‬‬

‫מסד נתונים יחסי ( ‪)Relational Database‬‬


‫המודל המקובל היום הוא למימוש מסדי נתונים ממוחשבים הוא מודל הנתונים היחסי‪ .‬מודל זה מיושם ע"י כל‬
‫היצרנים המובילים של מערכות לניהול מסדי נתונים‪ Microsoft ,Oracle ( .‬ו‪)IBM -‬‬
‫המודל היחסי פותח בסוף שנות ה‪ 60 -‬ע"י ד"ר קוד‪ .‬למודל היחסי שני מאפיינים עיקריים‪:‬‬
‫‪ )1‬מידע עצמו מאוחסן בטבלאות‪.‬‬
‫‪ )2‬בין הטבלאות מוגדרים קשרים או יחסים‬

‫מערכת לניהול מסדי נתונים יחסיים (‪)Relational Database Management System‬‬


‫מערכת המיועדת לניהול מאגרי מידע גדולים‪ ,‬כאשר ניהול משמעותו‪:‬‬
‫‪ ‬הגדרת מבנים לאחסון מידע‪.‬‬
‫‪ ‬אספקת כלים ושיטות לשליפה‪ ,‬טיפול ועיבוד המידע‪.‬‬
‫‪ ‬הגנה על נתונים מפני תקלות מחשב ומפני ניסיונות של גורמים לא מוסמכים להשתמש בהם‪.‬‬
‫‪ ‬פיקוח על גישה בו זמנית של משתמשים אחדים לבסיס הנתונים‪.‬‬
‫דוגמה למערכת ניהול כזו‪ SQL Server :‬של חברת ‪. Microsoft‬‬

‫עמוד ‪3‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫שפת ‪SQL‬‬
‫ראשי תיבות‪Structured Query language :‬‬
‫השפה בעזרתה עובדים מול מסדי נתונים יחסיים‪ .‬מאפשרת יצירה‪ ,‬ניהול ותשאול של מסדי נתונים יחסיים‪.‬‬
‫מדובר בשפה סטנדרטית שאומצה ע"י כל יצרני ה ‪ RDBMS‬בעולם‪.‬‬
‫ניתן לחלק את השפה למספר קטגוריות של פקודות‪.‬‬
‫פקודות ‪ – SELECT‬פקודות שמטרתן היא שליפת הנתונים מתוך הטבלאות‪.‬‬
‫פקודות ‪ -)data manipulation language( DML‬אוסף פקודות המאפשרות לבצע מניפולציות על נתונים‪.‬‬
‫למשל להזין רשומה חדשה לטבלה או עדכון של רשומה קיימת‪.‬‬
‫כולל את הפקודות ‪ Update ,Insert‬ו ‪.Delete‬‬
‫פקודות ‪ -)data definition language) DDL‬אוסף פקודות להגדרת הישויות הנחוצות בבסיס הנתונים‬
‫והקשרים ביניהן‪ .‬למשל יצירת טבלה‪.‬‬
‫כולל את הפקודות ‪ Alter ,Create,Truncate‬ו ‪.Drop‬‬
‫פקודות ‪ – )Data Control Language( DCL‬אוסף פקודות המאפשרות לנהל הרשאות במסד הנתונים‪.‬‬
‫כולל את הפקודות ‪ Deny ,Grant‬ו ‪.Revoke‬‬
‫שפת ‪T-SQL‬‬
‫כאמור‪ ,‬כל יצרניות ה ‪ RDBMS -‬אימצו את שפת ‪ SQL‬כסטנדרט‪ ,‬אולם כולן גם הרחיבו את הסטנדרט‬
‫והוסיפו פקודות ייחודיות משלהן לשפה‪ .‬התוצאה בעולם של ‪ SQL Server‬היא שפת ‪ .Transact-SQL‬שפה‬
‫זו כוללת את הפקודות הסטנדרטיות שמהוות את שפת ‪ SQL‬ובנוסף כוללת פקודות נוספות הייחודיות ל ‪SQL‬‬
‫‪.Server‬‬
‫כמה עובדות על שפת ‪ T-SQL‬בסביבת ‪SQL SERVER‬‬

‫משפטי ‪ SQL‬אינם ‪.Case Sensitive‬‬ ‫‪‬‬


‫ניתן לכתוב משפט בודד במספר שורות או בשורה אחת‪.‬‬ ‫‪‬‬
‫אסור לרדת שורה באמצע מילה‪.‬‬ ‫‪‬‬
‫שימ וש ברווחים והזחות מותרים ורצוי עבור קריאות המשפטים‪.‬‬ ‫‪‬‬

‫אילוצים ‪Constraints‬‬
‫בעבודה מול מסד נתונים‪ ,‬אחד הדברים החשבים ביותר הוא אמינות הנתונים ( ‪ .)Data integrity‬כלומר‪ ,‬חשוב‬
‫שעל עמודות מסויימות יקבעו חוקים שימנעו כניסת נתוני "זבל" לתוכן‪ .‬חוקים אלה נקראים אילוצים‪.‬‬

‫האילוצים הקיימים הם‪:‬‬


‫‪ -(NN) NOT NULL.1‬חובת הזנה‪ .‬למשל‪ -‬עמודת שם משפחה של עובד היא עמודת חובה (‪)not null‬‬
‫ולעומתה עמודת שם אמצעי היא עמודת רשות עליה לא מוגדר החוק‪.‬‬

‫‪ -(UK) UNIQUE .2‬יחודיות‪ .‬אילוץ ‪ Unique‬פירושו שלא יופיעו ערכים כפולים בעמודה מסויימת‪ .‬למשל‬
‫עמודת מספר תעודת זהות‪ ,‬עמודת מספר דרכון וכו'‪.‬‬
‫ניתן להגדיר את ‪ Unique‬על עמודה אחת או על שילוב של כמה עמודות (למשל השילוב של קידומת ומספר‬
‫טלפון צריך להיות יחודי)‬
‫ב‪ SQL-SERVER -‬מותר שיהיה רק ערך ‪ NULL‬אחד בעמודה המוגדרת ‪.Unique‬‬
‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪4‬‬
‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪ -(CK) CHECK.3‬בדיקה‪ .‬אפשר לבקש בדיקה מסויימת עבור עמודות‪ .‬למשל אפשר לבדוק שמחירו של מוצר‬
‫תמיד חיובי‪ ,‬או שתאריך הלידה קטן מתאריך תחילת העבודה וכו'‪.‬‬

‫‪ - (PK) Primary Key .4‬מפתח ראשי‪ .‬עמודת מפתח ראשי היא למעשה עמודה שהערכים בה שונים זה‬
‫מזה (כמו ‪ , )UNIQUE‬וכן יש בה חובת הזנה (כמו ‪ .)NOT NULL‬עמודת המפתח הראשי עוזרת לזהות‬
‫רשומות מסויימות בצורה פשוטה ומהירה‪.‬‬
‫בכל טבלה יכול להיות רק מפתח ראשי אחד‪ ,‬שיכול להיות מוגדר על עמודה בודדת (למשל קוד מוצר) או על‬
‫שילוב עמודות‪.‬‬

‫‪ - (FK) FOREIGN KEY .5‬מפתח זר‪ .‬עמודה המקשרת בין טבלאות‪ .‬זו למעשה עמודה הנשענת על עמודה‬
‫אחרת‪ .‬עמודת כזו יכולה להשען על מפתח ראשי או ‪.UNIQUE‬‬
‫העמודה עליה מוגדר ה ‪ FK‬היא עמודת ה"בת" (‪ )child‬ואילו העמודה עליה היא נשענת נראת עמודת ה"אם"‬
‫(‪)parent‬‬
‫עמודת ‪ FK‬יכולה להכיל בתוכה רק ערכים הקיימים בעמודת האם (או ‪.)NULL‬‬
‫בד"כ כאשר אומרים שיש "קשר" בין טבלאות הכוונה היא לקשר ‪PK-FK‬‬

‫*להסבר מפורט יותר על תכנון מבנה הטבלאות ראה נספח ראשון‪ :‬ניתוח ועיצוב מודל הנתונים‬

‫בסיסי הנתונים עמם נעבוד‬


‫במהלך הקורס נשתמש בבסיסי נתונים לדוגמה‪ ,‬המגיעים עם התקנת ‪.SQL Server‬‬
‫בסיסי הנתונים שנעבוד עמם הם‪:‬‬

‫‪ – NorthWind‬בסיס נתונים המכיל מידע לגבי חברה המייבאת ומייצאת מזון יחודי מכל העולם‪.‬‬
‫‪ - Pubs‬בסיס נתונים המכיל מידע לגבי חברת הוצאת ספרים‪.‬‬

‫‪SQL Server Versions‬‬

‫עמוד ‪5‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫בסיס הנתונים ‪NorthWind‬‬

‫הטבלאות הקיימות בבסיס הנתונים ‪ NorthWind‬בהן נשתמש‪:‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪6‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫עמוד ‪7‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬
‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪8‬‬
‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫הקשרים בין הטבלאות בבסיס הנתונים ‪ NorthWind‬מוצגים בדיאגרמה הבאה‪:‬‬

‫עמוד ‪9‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫בסיס הנתונים ‪:Pubs‬‬
‫הטבלאות הקיימות בבסיס הנתונים ‪ Pubs‬שבהן נשתמש‪:‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪10‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫עמוד ‪11‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬
‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫הקשרים בין הטבלאות בבסיס הנתונים ‪ Pubs‬מוצגים בדיאגרמה הבאה‪:‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪12‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫עבודה עם ‪sql server managment studio – SSMS‬‬

‫‪Connecting to SQL Server‬‬

‫מתיבת החיפוש בתפריט התחל הקישו ‪SSMS‬‬


‫תיפתח תיבת דו שיח‪Connect to server :‬‬

‫‪ :Server type‬לניהול ואיחזור מידע מ‪ DB -‬נבחר ‪.Dtatabase Engine‬‬


‫‪ :Server Name‬לאיזה ‪ -Server( Instance‬שרת) אליו ברצוננו להתחבר‪.‬‬
‫‪ : Authentication‬מהי צורת ההזדהות של המשתמש מול השרת‪.‬‬
‫‪– Windows authentication‬משתמש המנסה לבצע חיבור לשרת זיהויו מתבצע ע"י מערכת‬
‫ההפעלה ואין צורך להזדהות מול ‪.sql server‬‬
‫‪ – Sql server Authentication‬זיהוי המשתמש מתבצע מול ‪ sql server‬ולכן יש לספק‪:‬‬
‫‪ – Login‬שם משתמש‬
‫‪ – Password‬סיסמה‬

‫בסיום התהליך להקיש על לחצן ‪.Connect‬‬

‫עמוד ‪13‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Working with Object Explorer‬‬

‫‪ Object explorer‬הינו כלי גרפי המאפשר לנהל את ה‪ Databases -‬ואת האובייקטים שלו כגון‪ :‬טבלאות‪,‬‬
‫‪ Stored Procedures ,Views‬וכו‪...‬‬

‫על מנת להציג את האובייקטים השונים ‪:‬‬


‫‪ .1‬להרחיב את תיקיית ‪ Databases‬כדי להציג את ה‪ DB -‬הקיימים‬
‫בו‪.‬‬
‫‪ .2‬להרחיב את ה‪ DB -‬הרצוי כדי להציג את הטבלאות הקיימות בו‪.‬‬
‫‪ .3‬להרחיב את הטבלאות כדי לצפות באובייקטי הטבלאות הקיימים‬
‫בו‪.‬‬
‫‪ .4‬להרחיב טבלה רצויה כדי לצפות במבנה שלה‪ :‬עמודות‪ ,‬אילוצים‪,‬‬
‫אינדקסים ‪.‬‬
‫‪ .5‬בהרחבת תיקיית ‪ Column‬של כל טבלה ‪ ,‬ניתן לראות את שמות‬
‫העמודות‪ ,‬טיפוסי נתונים‪ ,‬ומפתח ראשי ומשני‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪14‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪ - 1‬פקודת ‪SELECT‬‬

‫מבנה הפקודה המלא‪:‬‬


‫]‪Select * / [DISTINCT] column_name [,column_name..‬‬
‫‪From table_name‬‬
‫]‪[where condition‬‬
‫]‪[group by column_name‬‬
‫]‪[having condition‬‬
‫]‪[order by column_name‬‬

‫שימוש‪:‬‬
‫משפט ‪ select‬מאפשר לקבל חתכי מידע שונים מתוך הטבלאות שבמאגר הנתונים‪.‬‬
‫ניתן לשלב במשפט חלקים שונים בהם נדון במהלך הפרקים הבאים‪.‬‬

‫בחירת כל העמודות מהטבלה תתבצע ע"י שימוש באופרטור * (כוכבית)‪.‬‬

‫דוגמה ‪:‬‬

‫בסיס נתונים‪.Northwind:‬‬
‫בחירת כל העמודות שבטבלת ‪Employees‬‬

‫* ‪Select‬‬
‫‪From Employees‬‬
‫סדר העמודות בפלט יהיה זהה לסדר העמודות המוגדר בטבלה‪ .‬שמות העמודות בטבלה יהוו את שמות‬
‫העמודות בפלט‪.‬‬
‫הצגת עמודות מסוימות מהטבלה‬

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

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫שליפה של עמודה אחת בלבד‪ ,‬למשל‪ ,‬בחירת השמות הפרטיים של כל העובדים שבטבלת ‪.Employees‬‬

‫‪Select FirstName‬‬
‫‪From Employees‬‬

‫עמוד ‪15‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫התוצאה‪:‬‬

‫‪FirstName‬‬
‫‪----------‬‬
‫‪Nancy‬‬
‫‪Andrew‬‬
‫‪Janet‬‬
‫‪Margaret‬‬
‫‪Steven‬‬
‫‪Michael‬‬
‫‪Robert‬‬
‫‪Laura‬‬
‫‪Anne‬‬
‫‪shay‬‬
‫‪shay‬‬

‫)‪11(row(s) affected‬‬

‫כפי שניתן לראות בתוצאה ‪ FirstName‬הינה הכותרת עבור שמות העובדים‪.‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫שליפה של מספר עמודות‪ ,‬למשל‪ ,‬בחירת מספר עובד ‪,‬שם פרטי ושם משפחה של כל העובדים שבטבלת‬
‫‪Employees‬‬

‫‪Select EmployeeID,FirstName, LastName‬‬


‫‪From Employees‬‬
‫מתן שמות חלופיים לעמודות ‪Alias -‬‬

‫כאמור‪ ,‬באופן אוטמטי כותרת עמודה בתוצאה היא שם השדה בבסיס הנתונים‪ .‬אם רוצים להציג עמודה תחת‬
‫כותרת אחרת יש לתת לה כינוי (‪.)alias‬‬
‫"‪SELECT column_name AS "Alias‬‬
‫‪FROM table_name‬‬
‫דגשים‬
‫‪ .1‬אם הכינוי לא מכיל תוים אסורים (למשל רווח) ואינו מילה שמורה (למשל ‪ ,)select‬אין חובה להוסיף את‬
‫הגרשיים‪.‬‬
‫למשל במקרה בו מכנים עמודה ‪ f_name‬אין חובה להשתמש בגרשיים‪.‬‬
‫‪Select FirstName AS f_name‬‬
‫‪From Employees‬‬
‫ואילו במקרה בו מכנים אותה ‪ , First Name‬חייבים להשתמש בגרשיים‪.‬‬
‫"‪Select FirstName AS " First name‬‬
‫‪From Employees‬‬

‫‪ .2‬המילה ‪ AS‬היא אופציונאלית‪ ,‬ומשמשת לקריאות בלבד‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪16‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫שירשור מספר שדות וטקסט חופשי תחת עמודה אחת בתוצאה‬

‫שירשור פירושו הצגת שילוב שדות כשדה אחד בפלט‪ .‬כשם שניתן לשרשר שדות‪ ,‬אפשר לשרשר גם טקסט‬
‫חופשי‪ .‬השירשור מתבצע באמצעות האופרטור ‪.+‬בשרשור טקסט חופשי‪ ,‬יש לתחום את הטקסט בגרשים‪.‬‬
‫כתוצאה מפעולת השרשור העמודה תקבל את הכותרת ‪ no column name‬בפלט‪ ,‬לכן רצוי לתת לה כינוי‬
‫(‪.)alias‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הצגת פרטי העובדים שבטבלת ‪ Employees‬באופן הבא‪:‬‬
‫תחת עמודה בשם ‪ name‬יופיעו שמו הפרטי ושם משפחתו של העובד ובעמודה נפרדת יופיע מספרו של‬
‫העובד‪ .‬שים לב שרשור של מלל בין העמודות דורש שימוש בגרש בודד מכל צד של המחרוזת הנוספת‬
‫לשרשור‪.‬‬

‫‪Select FirstName+’ ‘+ LastName as Name, EmployeeID‬‬


‫‪From Employees‬‬

‫התוצאה‪:‬‬
‫‪Name‬‬ ‫‪EmployeeID‬‬
‫‪----------- -------------------------------‬‬
‫‪Nancy Davolio‬‬ ‫‪1‬‬
‫‪Andrew Fuller‬‬ ‫‪2‬‬
‫‪Janet Leverling‬‬ ‫‪3‬‬
‫‪Margaret Peacock 4‬‬
‫‪Steven Buchanan‬‬ ‫‪5‬‬
‫‪Michael Suyama‬‬ ‫‪6‬‬
‫‪Robert King‬‬ ‫‪7‬‬
‫‪Laura Callahan‬‬ ‫‪8‬‬
‫‪Anne Dodsworth‬‬ ‫‪9‬‬
‫‪shay Fuller‬‬ ‫‪15‬‬
‫‪shay ddd‬‬ ‫‪16‬‬

‫)‪)11 row(s) affected‬‬

‫שים לב פעולת שירשור זו אינה סטנדרטית‪ .‬היא מתאימה ל‪ SQL Server -‬ואך לא תתאים בהכרח לסביבות‬
‫אחרות!‬

‫עמוד ‪17‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫שימוש בפעולות אריתמטיות בעמודות התוצאה‬

‫ניתן לשלב פעולות חשבוניות על הערכים המוחזרים וביניהם‪.‬‬


‫הפעולות החשבוניות הבסיסיות הן‪:‬‬
‫‪ +‬חיבור‬ ‫‪‬‬
‫‪ -‬חיסור‬ ‫‪‬‬
‫* כפל‬ ‫‪‬‬
‫‪ /‬חילוק‬ ‫‪‬‬
‫‪ -)modulo( % ‬החזרת שארית מחלוקה בין ‪ 2‬מספרים‪.‬‬

‫כפל וחילוק קודמים לחיבור וחיסור‪ ,‬אלא אם היה שימוש בסוגריים‪.‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫בחירת שמות המוצרים‪,‬מחירם הרגיל (כפי שהוא מוגדר בבסיס הנתונים) ומחירם לאחר תוספת של ‪18%‬‬
‫(המוצרים מטבלת ‪.)products‬‬

‫‪select ProductName, UnitPrice, UnitPrice*1.18‬‬


‫‪from products‬‬

‫* גם בביצוע פעולה ארתמטית על עמודה תתקבל הכותרת ‪ ,No colum name‬ולכן במקרה זה ממולץ לתת‬
‫לעמודה כינוי (‪.)alias‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הצגת שמות המוצרים ומחיריהם לאחר ‪ 10%‬הנחה‪.‬‬

‫"‪Select ProductName, UnitPrice*0.9 AS "New Price‬‬


‫‪From products‬‬

‫פתרון בעיית כפילות של רשומות חוזרות‬

‫ניתן למנוע חזרה של רשומות זהות בתוצאה ע"י שימוש במילה ‪.DISTINCT‬‬

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

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫בחירת ה‪ id-‬של כל הלקוחות שביצעו הזמנה כלשהי‪.‬‬
‫‪Select distinct CustomerID‬‬
‫‪From Orders‬‬

‫* ‪ DISTINCT‬יכול לשמש בשאילתא עם עמודה אחת או כמה‪.‬‬


‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪18‬‬
‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫דוגמה‬
‫בסיס הנתונים ‪NorthWind‬‬
‫בחירת שילובים יחודיים של מספר קטגוריה ומספר ספק מטבלאת המוצרים‪.‬‬
‫‪SELECT DISTINCT CategoryID, SupplierID‬‬
‫‪FROM Products‬‬

‫התוצאה‪:‬‬
‫‪CategoryID‬‬ ‫‪SupplierID‬‬
‫‪----------- -------- ----------------------‬‬
‫‪1‬‬ ‫‪1‬‬
‫‪1‬‬ ‫‪7‬‬
‫‪1‬‬ ‫‪10‬‬
‫‪2‬‬ ‫‪1‬‬
‫‪2‬‬ ‫‪2‬‬
‫‪2‬‬ ‫‪3‬‬
‫…‬ ‫…‬
‫* מספר קטגוריה יכול לחזור כמה פעמים‪ ,‬כל פעם בשילוב עם מספר ספק אחר‪.‬‬

‫הכנסת הערות לתוך קוד ‪SQL‬‬

‫ניתן להכניס תיעוד והסברים לתוך קוד ‪ SQL‬ע"י שימוש בהערת שורה או הערת מקטע‪.‬‬
‫תיעוד קוד ‪ T-SQL‬אינו פוגע בביצועים! מכיוון שהן אינן נקראות בהרצת הקוד‪.‬‬

‫הערת שורה‪:‬‬

‫‪-- This whole line is a comment‬‬


‫‪SELECT lastname, firstname -- end of a line‬‬
‫‪FROM employees‬‬

‫הערת מקטע‪:‬‬

‫*‪/‬‬
‫‪All the text in this paragraph will be treated as comments‬‬
‫‪by SQL Server.‬‬
‫‪*/‬‬

‫עמוד ‪19‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪ - 2‬משפט ה ‪WHERE‬‬
‫ניתן לבצע סינון של הרשומות החוזרות ע"י הוספת משפט ה ‪ where‬למשפט ה‪.select -‬‬
‫לאחר המילה ‪ where‬יופיע תנאי אחד או מספר תנאים אשר יגבילו את הרשומות החוזרות ‪.‬‬

‫סינטקס‪:‬‬
‫]‪SELECT * / [DISTINCT] column_name [,column_name..‬‬
‫‪FROM table_name‬‬
‫] … ערך אופרטור עמודה ‪ [ AND / OR‬ערך אופרטור עמודה ‪WHERE‬‬

‫את האופרטורים אפשר לחלק לשתי קבוצות‪ :‬פשוטים ומורכבים‪.‬‬


‫אופרטורי השוואה פשוטים‪:‬‬
‫=‬
‫>‬
‫<‬
‫=>‬
‫=<‬
‫≠‬ ‫<>‬
‫=!‬
‫<!‬
‫>!‬

‫אופרטורים פשוטים יכולים לעמוד מול מספרים‪ ,‬מחרוזות ותאריכים‪.‬‬


‫ערך מחרוזתי או תאריכי צריך להופיע בגרשים‪ ,‬ואילו ערך מספרי לא‪.‬‬

‫שלוש הדוגמאות מבסיס הנתונים ‪NorthWind‬‬


‫דוגמה‪:‬‬
‫בחירת שמות כל המוצרים מטבלת ‪ Products‬אשר מספר היחידות הקיים מהם במלאי אינו עולה על ‪.10‬‬
‫‪Select ProductName‬‬
‫‪From Products‬‬
‫‪Where UnitsInStock >=10‬‬
‫דוגמה‪:‬‬
‫בחירת כל הפרטים של כל העובדים שבטבלת ‪ Employees‬אשר גרים בעיר ‪.London‬‬

‫* ‪Select‬‬
‫‪From Employees‬‬
‫'‪Where City='London‬‬

‫דוגמה‪:‬‬
‫שליפת פרטי ההזמנות שהגיעו ליעדן באיחור‪( .‬כלומר שתאריך המשלוח שלהן מאוחר מתאריך הדרישה)‪.‬‬
‫* ‪SELECT‬‬
‫‪FROM Orders‬‬
‫‪WHERE ShippedDate < RequiredDDate‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪20‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫אופרטורי השוואה מורכבים‪:‬‬

‫…‪ -Between…And‬מאפשר לבדוק אם ערך בשדה נמצא בטווח ערכים מסוים‪ .‬האופרטור ‪NOT ...‬‬ ‫‪‬‬
‫‪ Between…And‬מאפשר לראות אם ערך נמצא מחוץ לטווח ערכים מסויים‪.‬‬
‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫בחירת שמות כל המוצרים מטבלת ‪ Products‬אשר מספר היחידות הקיים מהם בין ‪10‬‬
‫ל‪.20 -‬‬

‫‪Select ProductName‬‬
‫‪From Products‬‬
‫‪Where UnitsInStock Between 10 and 20‬‬

‫הערות‪:‬‬
‫‪ )1‬האופרטור ‪ Between‬כולל בטווח המבוקש גם את ערכי הקצה‪.‬‬
‫בדוגמה לעיל נקבל גם את המוצרים שמחירם בדיוק ‪ 10‬או ‪.20‬‬
‫‪ ) 2‬סדר הערכים חשוב‪ .‬הערך הראשון צריך להיות הערך הקטן מבין השניים והערך‬
‫הגבוה צריך להופיע שני‬

‫‪ – IN ‬מאפשר השוואה מול רשימת ערכים‪ .‬בודק למעשה אם השדה שווה לאחד הערכים ברשימה‪ .‬בין‬
‫הערכים פועל אלגוריתם של ‪( OR‬יפורט בהמשך)‪ .‬האופרטור ‪ NOT IN‬מאפשר למצוא שדה שערכו שונה‬
‫מרשימת ערכים ‪,‬במקרה כזה פועל בין הערכים אלגוריתם של ‪( AND‬יפורט בהמשך)‪.‬‬
‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫בחירת כל הפרטים של כל העובדים שבטבלת ‪ ,Employees‬אשר גרים בעיר ‪ London‬או ‪ Seattle‬או‬
‫‪.Tacoma‬‬
‫* ‪Select‬‬
‫‪From Employees‬‬
‫)‘‪Where City in ('London‘ ,’ Seattle‘,’ Tacom‬‬

‫‪ - LIKE‬אופרטור זה מאפשר לבצע השוואה לחלקי מילים‪ .‬שימושם נפוץ בשאילתות חיפוש כאשר הביטוי‬ ‫‪‬‬
‫המלא\המדוייק אותו מחפשים לא ידוע‪ .‬החיפוש מתבצע בעזרת תווי ההכללה הבאים‪:‬‬

‫אוסף כלשהו של תווים‪ ,‬יכול להכיל אפס תווים ויותר‪.‬‬ ‫‪%‬‬


‫מייצג תו בודד כלשהו ומתאים למחרוזת בעלת תו אחד בלבד‪.‬‬ ‫_‬
‫מ ייצג תו אחד בלבד שבתוך טווח ערכים (לדוגמה ]‪ [a-f‬זהה ל ]‪) [abcdef‬‬ ‫][‬
‫מייצג תו אחד בלבד שאינו בטווח הערכים (לדוגמה ]‪ [^a-f‬זהה ל‪) [^abcdef] -‬‬ ‫]^[‬

‫עמוד ‪21‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
. LIKE ‫ בתוך תנאי החיפוש‬wildcards -‫הטבלה הבאה מציגה מספר דוגמאות לשימוש ב‬

Expression Returns
LIKE '[a-cdf]%' a, b, c, d, or f %
LIKE '[-acdf]%' -, a, c, d, or f %
LIKE 'abc_d%' abc_d%
LIKE 'abc[def]' abcd, abce, and abcf

:‫דוגמה‬
.Northwind:‫בסיס נתונים‬
.A ‫ אשר שמם הפרטי מתחיל באות‬Employees ‫בחירת כל הפרטים של כל העובדים שבטבלת‬
Select *
From Employees
Where FirstName LIKE 'A%'

:‫דוגמה‬
.Northwind:‫בסיס נתונים‬
‫ אשר המיקוד שלהם מתחיל במספר לא מכיל‬Employees ‫בחירת כל הפרטים של כל העובדים שבטבלת‬
.9 ‫את הספרה‬
* Select
From Employees
where postalcode NOT LIKE '%9%'

‫ תחזיר‬,NULL ‫ או השוואה ל‬NULL ‫ וכל חישוב עם‬.‫ מייצג ערך בלתי ידוע‬NULL ‫ הערך‬- IS NULL 
‫ במקום זה יש להשתמש במשפט‬.‫ יחזיר תוצאה ריקה‬WHERE value = NULL ‫ הביטוי‬,‫ לכן‬.NULL
‫ לשליפת‬IS NOT NULL ‫ או ב‬NULL ‫ לשליפת השדות שיש בהם‬IS NULL ‫ באופרטור‬Where -‫ה‬
.‫השדות שיש בהם ערך ידוע כלשהו‬

‫דוגמה‬
‫ עבור אותן‬Customers ‫ מטבלת‬CustomerID, CompanyName, and Region ‫שולפת את העמודות‬
.‫רשומות הנמצאות באזור בלתי ידוע‬

SELECT CustomerID, CompanyName, Region


FROM Customers
WHERE Region IS NULL
:‫התוצאה‬
CustomerID CompanyName Region
-------------- ----------------------------------------------- ----------
ALFKI Alfreds Futterkiste NULL
ANATR Ana Trujillo Emparedados y helados NULL
ANTON Antonio Moreno Taqueroa NULL
:

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 22 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫שימוש באופרטורים לוגיים לשילוב יותר מתנאי אחד‬
‫כאשר רוצים לשלב יותר מתנאי אחד ניתן להשתמש באופרטור ‪ or‬או ‪ .and‬כשנשתמש באופרטור ‪ or‬מספיק‬
‫כי אחד מהתנאים יתקיים‪ ,‬בעוד שימוש באופרטור ‪ and‬מחייב את התקיימות כל התנאים‪.‬‬

‫טבלת ‪:And‬‬

‫‪And‬‬ ‫‪True‬‬ ‫‪False‬‬ ‫‪Null‬‬


‫‪True‬‬ ‫‪True‬‬ ‫‪False‬‬ ‫‪Null‬‬
‫‪False‬‬ ‫‪False‬‬ ‫‪False‬‬ ‫‪False‬‬
‫‪Null‬‬ ‫‪Null‬‬ ‫‪False‬‬ ‫‪Null‬‬

‫טבלת ‪:Or‬‬

‫‪Or‬‬ ‫‪True‬‬ ‫‪False‬‬ ‫‪Null‬‬


‫‪True‬‬ ‫‪True‬‬ ‫‪True‬‬ ‫‪True‬‬
‫‪False‬‬ ‫‪True‬‬ ‫‪False‬‬ ‫‪Null‬‬
‫‪Null‬‬ ‫‪True‬‬ ‫‪Null‬‬ ‫‪Null‬‬

‫שימוש באופרטור השלילה‬


‫שימוש באופרטור ‪ not‬מאפשר לשלול כל תנאי המשתמש באחד האופרטורים שצוינו קודם‪.‬‬

‫טבלת ‪:Not‬‬

‫‪Not‬‬ ‫‪True‬‬ ‫‪False‬‬ ‫‪Null‬‬


‫‪False‬‬ ‫‪True‬‬ ‫‪Null‬‬

‫סדר עדיפות האופרטורים‬


‫האופרטורים מצוינים מבעלי העדיפות הגבוהה לנמוכה בהנחה שאין סוגריים שכן אלו נותנים עדיפות גבוהה‬
‫יותר‪.‬‬
‫‪ .1‬אופרטורי ההשוואה השונים (כולל אופרטורי רשימה‪ ,‬טווח וכד')‬
‫‪Not .2‬‬
‫‪And .3‬‬
‫‪Or .4‬‬

‫עמוד ‪23‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
:‫דוגמה‬
.Northwind:‫בסיס נתונים‬
-‫ ומחירם גדול מ‬20 -‫ אשר מספר היחידות הקיים מהם קטן מ‬Products ‫בחירת שמות כל המוצרים מטבלת‬
.30

select ProductName
from products
where UnitsInStock<20
and UnitPrice>30

:‫התוצאה‬
ProductName
----------------------------------------
Northwoods Cranberry Sauce
Alice Mutton
Gumb?r Gummib?rchen
Th?ringer Rostbratwurst
Mascarpone Fabioli
C?te de Blaye
Ipoh Coffee
Perth Pasties
Camembert Pierrot
Tarte au sucre
Mozzarella di Giovanni

11 row(s) affected))

Order By -‫מיון רשומות‬

‫ המיון יכול לכלול מיון ראשי בלבד או שילוב‬, order by ‫ניתן למיין את הרשומות החוזרות ע"י צרוף הפסוקית‬
.‫ מיון ברירת המחדל – סדר עולה‬.‫של מיון ראשי עם מיונים משניים‬

:‫דוגמה‬
.Northwind:‫בסיס נתונים‬
‫ביתי בסדר עולה‬-‫ מסודרות לפי סדר אלפא‬Categories ‫הצגת כל הקטגוריות שבטבלת‬

select CategoryName
from Categories
order by CategoryName

.‫ לאחר שם עמודת המיון‬DESC ‫מיון בסדר יורד יתבצע ע"י הוספת המילה‬
:‫דוגמה‬
select CategoryName
from Categories
order by CategoryName desc

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 24 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫הערות‪:‬‬
‫‪ )1‬במידה והשתמשנו ב‪ alias -‬לעמודה ניתן לבצע גם לפי שמו מיון‪.‬‬
‫‪ )2‬ניתן למיין לפי המיקום של עמודה בפסוקית ה ‪.Select‬‬

‫דוגמה‪:‬‬
‫‪Select ProductName, UnitPrice‬‬
‫‪From Products‬‬
‫‪Order By 2‬‬

‫בחירת "‪ "Top-n‬רשומות מתוך התוצאה שהתקבלה‬

‫ניתן לבחור ‪ n‬רשומות עליונות מתוצאת השאילתה שהתקבלה‪ ,‬כאשר ‪ n‬מייצג מספר שלם כלשהו‪.‬‬
‫יש לשלב את פקודת ה‪ TOP -‬יחד עם ‪ Order by‬כדי לקבל תוצאות שליפה משמעותיות יותר‪.‬‬

‫דוגמה ‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫‪select top 10 * from products‬‬

‫במקרה זה נקבל אך ורק את עשרת הרשומות הראשונות שחזרו כתוצאה מהרצת השאילתה‪.‬‬

‫‪WITH TIES‬‬

‫אופצייה זאת משולבת עם פקודת ‪ Top n‬כדי להביא את כל הרשומות התואמות לקבוצת הרשומות שנשלפו‬
‫באמצעות ה‪.top n -‬‬

‫דוגמה ‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫שליפה זאת תציג את ‪ 5‬המכירות האחרונות שהתבצעו מטבלת ‪Orders‬‬

‫‪SELECT TOP (5) orderid, customerid, orderdate‬‬


‫‪FROM Orders‬‬
‫;‪ORDER BY orderdate DESC‬‬
‫תוצאת השליפה תהיה‪:‬‬
‫‪Ordered‬‬ ‫‪customerid‬‬ ‫‪orderdate‬‬
‫‪11077‬‬ ‫‪RATTC‬‬ ‫‪1998-05-06 00:00:00.000‬‬
‫‪11076‬‬ ‫‪BONAP‬‬ ‫‪1998-05-06 00:00:00.000‬‬
‫‪11075‬‬ ‫‪RICSU‬‬ ‫‪1998-05-06 00:00:00.000‬‬
‫‪11074‬‬ ‫‪SIMOB‬‬ ‫‪1998-05-06 00:00:00.000‬‬
‫‪11073‬‬ ‫‪PERIC‬‬ ‫‪1998-05-05 00:00:00.000‬‬

‫עמוד ‪25‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫האופציה של ‪ WITH TIES‬תשלוף את כל הרשומות הקשורות לתאריך '‪'1998-05-05‬‬

‫‪SELECT TOP (5) WITH TIES orderid, customerid, orderdate‬‬


‫‪FROM Orders‬‬
‫;‪ORDER BY orderdate DESC‬‬

‫תוצאת השליפה תהיה‪:‬‬


‫‪Ordered customerid‬‬ ‫‪orderdate‬‬

‫‪11077‬‬ ‫‪RATTC‬‬ ‫‪1998-05-06 00:00:00.000‬‬


‫‪11076‬‬ ‫‪BONAP‬‬ ‫‪1998-05-06 00:00:00.000‬‬
‫‪11075‬‬ ‫‪RICSU‬‬ ‫‪1998-05-06 00:00:00.000‬‬
‫‪11074‬‬ ‫‪SIMOB‬‬ ‫‪1998-05-06 00:00:00.000‬‬
‫‪11073‬‬ ‫‪PERIC‬‬ ‫‪1998-05-05 00:00:00.000‬‬
‫‪11072‬‬ ‫‪ERNSH‬‬ ‫‪1998-05-05 00:00:00.000‬‬
‫‪11071‬‬ ‫‪LILAS‬‬ ‫‪1998-05-05 00:00:00.000‬‬
‫‪11070‬‬ ‫‪LEHMS‬‬ ‫‪1998-05-05 00:00:00.000‬‬

‫‪Top N Percent‬‬

‫לאופרטור ‪ Top‬יש וריאציה נוספת המאפשרת לשלוף ‪ n‬אחוזים ראשונים של הרשומות מתוצאות השאילתה‪.‬‬

‫דוגמה ‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬

‫‪select top 10 Percent * from products‬‬

‫הערה‪:‬‬
‫בד"כ נעשה שימוש בסעיף ה ‪ Top -‬בשילוב עם סעיף ה ‪ Order By -‬שידון בהמשך הפרק‪ .‬סעיף ה‪Order -‬‬
‫‪ By‬מאפשר למיין את הרשומות לפי הערכים בעמודה מסויימת‪ .‬כך למשל נוכל לשלוף את עשרת המוצרים‬
‫היקרים ביותר מתוך טבלת ‪.Products‬‬

‫דוגמה ‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫* ‪Select Top 10‬‬
‫‪From Products‬‬
‫‪Order By UnitPrice Desc‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪26‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪OFFSET - FETCH‬‬

‫במסגרת החידושים והשינויים מ ‪ SQL Server 2012 -‬התווסף אפשרות של ‪OFFSET – FETCH‬‬
‫שמאפשר ל"דפדף" בתוך תוצאת שאילתה ‪ ,‬להתחיל מאיזו שורה שרוצים ולהביא ‪ ,‬יחסית לשורה זו‪ ,‬כמה‬
‫שורות שרוצים‪.‬‬

‫מבנה הפקודה‪:‬‬

‫}‪OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS‬‬


‫{ } ‪[FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression‬‬
‫| ‪ROW‬‬
‫]‪ROWS } ONLY‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫נניח שאנו מעוניינים להחזיר מטבלת ‪ Orders‬המכילה ‪ 830‬רשומות‪ ,‬לדלג על ‪ 10‬רשומות‬
‫ראשונות (כלומר יתחיל משורה ‪ ,)11‬ולשלוף רק ‪ 10‬שורות הבאות אחריה‪.‬‬

‫‪SELECT orderid, customerid, orderdate‬‬


‫‪FROM Orders‬‬
‫‪ORDER BY orderid‬‬
‫; ‪offset 10 rows fetch next 10 rows only‬‬

‫‪ – Offset‬מציין את מספר רשומות ראשונות שידלג עליהם מהתוצאה הממוינת ויחזיר את‬
‫הרשומות הנותרות‪.‬חייב להיות מסופק בפקודה‪.‬‬

‫‪ – Fetch‬כמה רשומות מה‪ Fetch -‬להחזיר‪ .‬החלק האופציונלי בפקודה‪.‬‬

‫עמוד ‪27‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪ - 3‬פונקציות סקלריות‬
‫(‪)Scalar functions‬‬
‫תכנות בשפת ה ‪ SQL‬מאפשר שימוש בפונקציות ‪ .Scalar‬פונקציות אלו מקבלות ארגומנט אחד או יותר‬
‫ומחזירות ערך בודד‪ ,‬הן פועלות ברמת השורה ונחלקות לסוגים שונים‪:‬‬
‫‪ o‬פונקציות מתמטיות‬
‫‪ o‬פונקציות מחרוזתיות‬
‫‪ o‬פונקציות תאריכים‬
‫‪ o‬פונקציות המרה‬
‫‪ o‬פונקצית ‪ISNULL‬‬
‫שים לב כי פונקציות אלו אופייניות לבסיס הנתונים ‪ Microsoft SQL‬וקיימת סבירות כי בבסיס נתונים אחר‬
‫חלקן יעבדו באופן שונה‪.‬‬
‫ניתן להשתמש בפונקציות אלה במשפטי ה ‪ ,SELECT‬ה ‪ WHERE‬וה‪.ORDER BY -‬‬
‫* ניתן לקבל הרחבה לגבי כל אחת מהפונקציות בעזרת כלי העזרה על ידי שימוש ב ‪.F1+SHIFT‬‬

‫שימוש בפונקציות מתמטיות‪Mathematical Functions-‬‬

‫הפונקציות מקבלות ערך או קבוצת ערכים ומחזירות מספר כתוצאה‪.‬‬

‫‪CEILING‬‬ ‫)‪CEILING(numeric_expression‬‬ ‫הפונקציה מחזירה את הערך‬


‫השלם הגדול הקרוב ביותר‬
‫למספר שהתקבל כארגומנט‬
‫הפונקציה‪.‬‬
‫‪FLOOR‬‬ ‫)‪FLOOR(numeric_expression‬‬ ‫הפונקציה מחזירה את הערך‬
‫השלם הקטן הקרוב ביותר‬
‫למספר שהתקבל כארגומנט‬
‫הפונקציה‪.‬‬
‫‪ROUND‬‬ ‫‪ROUND(numeric_expression,‬‬ ‫הפונקציה מעגלת מספר‬
‫)]‪length[, function‬‬ ‫שהתקבל למספר המקומות‬
‫העשרוני שצוין‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪28‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫דוגמה‪:‬‬

‫דוגמה זו מחזירה את תקרת הערך של המספר ‪.8.4‬‬

‫)‪SELECT CEILING(8.4‬‬
‫תוצאת הרצת הקוד‪:‬‬

‫‪9.0‬‬
‫)‪(1 row(s) affected‬‬

‫דוגמה‪:‬‬
‫בסיס הנתונים ‪NorthWind‬‬
‫דוגמה זו מחזירה את העמודה ‪ UnitPrice‬מטבלת ‪ Products‬כולל מע"מ – ‪ 15%‬כאשר התוצאה מעוגלת‬
‫למקום ‪ 1‬אחרי הנקודה העשרונית‪.‬‬

‫‪SELECT ROUND (UnitPrice*1.155,1) FROM Products‬‬

‫תוצאת הרצת הקוד‪:‬‬

‫‪27.900000‬‬
‫‪29.500000‬‬
‫‪15.500000‬‬
‫‪:‬‬
‫‪20.200000‬‬

‫)‪(77 row(s) affected‬‬

‫עמוד ‪29‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פונקציות לטיפול במחרוזות ‪String Functions‬‬
‫פונקציות סקלאריות אלו מבצעות פעולות על מחרוזות המתקבלות כקלט ומחזירות מחרוזות או ערכים נומריים‪.‬‬
‫‪ASCII‬‬ ‫)‪ASCII(character_expression‬‬ ‫פונקציה המקבלת תו ומחזירה‬
‫הערך האסקי שלו‬
‫‪CHAR‬‬ ‫)‪CHAR(INTEGER_EXPRESSION‬‬ ‫פונקציה המקבלת מספר שלם‬
‫ומחזירה את התו המיוצג על ידו‬
‫בטבלת קודי האסקי‪.‬‬
‫‪CHARINDEX CHARINDEX(character_expression1,‬‬ ‫פונקציה המקבלת מחרוזת ותו‬
‫‪character_expression2‬‬ ‫לחיפוש ומחזירה את מיקום‬
‫)]‪[,start_location‬‬ ‫התו‪.‬‬

‫‪RIGHT‬‬ ‫‪RIGHT(character_expression,‬‬ ‫פונקציה המחזירה חלק ימני של‬


‫)‪integer_expression‬‬ ‫מחרוזת ממחרוזת שהתקבלה‬
‫בקלט‪.‬‬
‫‪LEFT‬‬ ‫‪LEFT(character_expression,‬‬ ‫פונקציה המחזירה חלק שמאלי‬
‫)‪integer_expression‬‬ ‫ממחרוזת‬ ‫מחרוזת‬ ‫של‬
‫שהתקבלה בקלט‪.‬‬

‫‪LEN‬‬ ‫)‪LEN(character_expression‬‬ ‫פונקציה המחזירה את אורך‬


‫המחרוזת‪.‬‬
‫‪RTRIM‬‬ ‫)‪RTRIM(character_expression‬‬ ‫פונקציה המחזירה מחרוזת‬
‫לאחר שקוצצו ממנה תווים‬
‫ריקים מצידה הימני‪.‬‬
‫‪LTRIM‬‬ ‫)‪LTRIM(character_expression‬‬ ‫פונקציה המחזירה מחרוזת‬
‫לאחר שקוצצו ממנה תוים‬
‫ריקים מצידה השמאלי‪.‬‬
‫‪REPLACE‬‬ ‫פונקציה המחליפה כל מופעי ‪REPLACE(' character _expression1',‬‬
‫‪'character_expression2',‬‬ ‫מחרוזת אחת במופעי מחרוזת‬
‫)'‪'character_expression3‬‬ ‫אחרת בתוך מחרוזת נתונה‪.‬‬
‫הינו‬ ‫הראשון‬ ‫הארגומנט‬
‫המחרוזת הנתונה‪ ,‬הארגומנט‬
‫השני המחרוזת המיועדת‬
‫להחלפה והארגומנט השלישי‬
‫המחרוזת החדשה‪.‬‬
‫‪REVERSE‬‬ ‫)‪REVERSE(character_expression‬‬ ‫פונקציה ההופכת את האותיות‬
‫במחרוזת‪.‬‬
‫פונקציה החותכת תת מחרוזת ‪SUBSTRING SUBSTRING(character _expression,‬‬
‫)‪start, length‬‬ ‫ממחרוזת‪.‬‬
‫‪LOWER‬‬ ‫)‪LOWER(character_expression‬‬ ‫פונקציה ההופכת את המחרוזת‬
‫לאותיות קטנות‪.‬‬
‫‪UPPER‬‬ ‫)‪UPPER(character_expression‬‬ ‫פונקציה ההופכת את המחרוזת‬
‫לאותיות גדולות‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪30‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫דוגמה ‪:‬‬
‫בדוגמה זו מחזירה הפונקציה ‪ LEN‬את מספר התווים במחרוזת‪.‬‬

‫)’‪SELECT LEN(‘ SQLSERVER‬‬


‫התוצאה המתקבלת מהרצת הקוד‬
‫‪-----------‬‬
‫‪9‬‬
‫)‪(1 row(s) affected‬‬

‫דוגמה‪:‬‬
‫הדוגמה הבאה עושה שימוש בפונקציות ‪ LTRIM‬ו‪ RTRIM -‬על מנת להסיר את התווים הריקים המובילים‬
‫(לפני התו ‪ )S‬והתווים הריקים העוקבים (אחרי התו ‪ )L‬מהמחרוזת‪.‬‬

‫)))' ‪SELECT LEN(RTRIM(LTRIM(' SQ L‬‬

‫התוצאה המתקבלת מהרצת הקוד‬


‫‪4‬‬
‫)‪(1 row(s) affected‬‬

‫דוגמה‪:‬‬
‫הדוגמה הבאה מדגימה איך הפונקציה מחזירה תת מחרוזת מתוך מחרוזת‪.‬‬
‫במקרה זה הפונקציה ‪ SUBSTRING‬מחזירה מהמחרוזת '‪ 5 'SQLSERVER‬תווים החל מהתו השני‪.‬‬
‫)‪SELECT SUBSTRING (‘SQLSERVER', 2,5‬‬

‫התוצאה המתקבלת מהרצת הקוד‬


‫‪QLSER‬‬
‫)‪(1 row(s) affected‬‬

‫עמוד ‪31‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פונקציות זמן ותאריך ‪Date and Time Functions -‬‬

‫פונקציות סקלאריות אלו מבצעות פעולות על תאריך וזמן המתקבלים כקלט ומחזירות מחרוזות‪ ,‬ערכים נומריים‬
‫או ערכי תאריך וזמן‪.‬‬

‫מרבית הפונקציות מקבלות פרמטר בשם ‪ DatePart‬אשר מייצג את החלק בתאריך אליו מתייחסים בשאילתה‪.‬‬

‫חלקי התאריך וייצוגם‪:‬‬


‫‪Datepart‬‬ ‫‪Abbreviations‬‬
‫‪Year‬‬ ‫‪yy, yyyy‬‬
‫‪Quarter‬‬ ‫‪qq, q‬‬
‫‪Month‬‬ ‫‪mm, m‬‬
‫‪Dayofyear‬‬ ‫‪dy, y‬‬
‫‪Day‬‬ ‫‪dd, d‬‬
‫‪Week‬‬ ‫‪wk, ww‬‬
‫‪Hour‬‬ ‫‪hh‬‬
‫‪Minute‬‬ ‫‪mi, n‬‬
‫‪Second‬‬ ‫‪ss, s‬‬
‫פונקציות התאריך והזמן‪:‬‬

‫‪DATEADD‬‬ ‫‪DATEADD(datepart,‬‬ ‫פונקציה המוסיפה ערכים לתאריך נתון ‪number,‬‬


‫)‪date‬‬
‫‪DATEDIFF‬‬ ‫פונקציה המחזירה הפרש בין ‪DATEDIFF(datepart, startdate, 2‬‬
‫)‪enddate‬‬ ‫תאריכים‬

‫‪DATENAME‬‬ ‫)‪DATENAME(datepart, date‬‬ ‫פונקציה המקבלת תאריך וחלק ממנו‬


‫(יום ‪,‬חודש ‪ )...‬ומחזירה את שמו‪.‬‬
‫‪DATEPART‬‬ ‫)‪DATEPART(datepart, date‬‬ ‫פונקציה המחזירה מספר המייצג את‬
‫החלק המבוקש בתאריך‬

‫‪DAY‬‬ ‫)‪DAY(date‬‬ ‫פונקציה המחזירה מספר המייצג את‬


‫שדה היום בתאריך שהוזן‪.‬‬

‫‪GETDATE‬‬ ‫)(‪GETDATE‬‬ ‫פונקציה המחזירה את התאריך הנוכחי‬

‫‪MONTH‬‬ ‫)‪MONTH(date‬‬ ‫פונקציה המחזירה את החלק המייצג‬


‫את החודש בתאריך שהוזן‪.‬‬

‫‪YEAR‬‬ ‫)‪YEAR(date‬‬ ‫פונקציה המחזירה את החלק המייצג‬


‫את השנה בתאריך שהוזן‪.‬‬
‫‪EOMONTH‬‬ ‫)‪EOMONTH(date , Interval‬‬ ‫פונקציה המחזירה את תאריך סוף‬
‫החודש יחסית לתאריך מסויים‪ .‬ניתן‬
‫להוסיף מספר אשר יציין כמה חודשים‬
‫לבדוק קדימה‪.‬‬
‫‪CURRENT_TIMESTAMP‬‬ ‫‪CURRENT_TIMESTAMP‬‬ ‫פונקציה המחזירה את התאריך הנוכחי‬
‫בדיוק של מאית השניה‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪32‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫דוגמה‪:‬‬

‫הדוגמה הבאה מחזירה ערך ‪ datetime‬חדש על ידי הוספת ‪ 21‬ימים לתאריך‪:‬‬


‫'‪.'11/25/2002‬‬

‫)'‪SELECT DATEADD(dd, 21, '2002-11-25‬‬


‫התוצאה המתקבלת מהרצת הקוד‬

‫‪2002-12-16 00:00:00.000‬‬
‫)‪(1 row(s) affected‬‬

‫דוגמה‪:‬‬

‫דוגמה זו מחשבת את ההפרש בימים בין שני התאריכים '‪ ‘1/1/2001‬ו‪.'1/2/2002' -‬‬

‫) '‪SELECT DATEDIFF(hh,'2001-01-01','2001-02-01‬‬

‫תוצאת הרצת הקוד‪:‬‬

‫‪8784‬‬
‫)‪(1 row(s) affected‬‬

‫דוגמה‪:‬‬

‫דוגמה זו מציגה את שם החודש הנוכחי‪.‬‬


‫))(‪SELECT DATENAME(month , getDate‬‬

‫דוגמה‪:‬‬

‫הדוגמה הבאה מחזירה את מספר הימים‪ ,‬מספר החודש והשנה מהתאריך ‪.03/22/2002‬‬

‫)'‪SELECT DAY('2002-03-22') , MONTH('22-2002-03'), YEAR('2002-03-22‬‬


‫תוצאת הרצת הקוד‬

‫‪22‬‬ ‫‪3‬‬ ‫‪2002‬‬

‫)‪(1 row(s) affected‬‬


‫דוגמה‪:‬‬

‫הדוגמה הבאה מציגה את חלקי התאריך של היום הנוכחי‪.‬‬

‫‪SELECT DATEPART(mm,GETDATE()), DATEPART(yy,GETDATE()),‬‬


‫))(‪DATEPART(dd,GETDATE‬‬

‫עמוד ‪33‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פונקציות המרה ‪CAST and CONVERT -‬‬

‫פונקציות אלו מטפלות בהמרה מפורשת של ביטוי מטיפוס נתונים אחד לאחר‪.‬‬
‫מוגדר‬ ‫והיא‬ ‫מאחר‬ ‫לשתיהן תפקודיות דומה‪ ,‬אך מומלץ להשתמש בפונקצית ה‪CAST -‬‬
‫כ‪.ANSI standard -‬‬

‫מבנה פונקצית ‪cast‬‬


‫)‪CAST(expression AS data_type‬‬

‫דוגמה ל‪: cast -‬‬


‫בדוגמה הבאה אנו ממירים ערך שמוגדר כ‪ datetime -‬למחרוזת‪.‬‬

‫))‪SELECT CAST (GETDATE() AS char(12‬‬

‫תוצאת הרצת הקוד‪:‬‬

‫‪DEC 20 2002‬‬

‫)‪(1 row(s) affected‬‬

‫מבנה פונקצית ‪convert‬‬

‫פקודת ה ‪ convert‬זהה בשימושה לפקודת ה ‪ ,cast‬אך היא מאפשרת בנוסף להמרה להוסיף סגנון ואינה‬
‫סטנדרטית‪.‬‬

‫)]‪CONVERT (data_type[(length)], expression [, style‬‬

‫דוגמה ל ‪: convert‬‬
‫בדוגמה הבאה אנו ממירים ערך שמוגדר כ‪ datetime -‬למחרוזת עיצוב המחרוזת נקבע בהתאם לקוד תבנית‬
‫עיצוב‪(,‬ניתן לקבל את תבניות העיצוב השונות מתפריט העזרה)‪.‬‬

‫)‪SELECT CONVERT (char(12), GETDATE(), 101‬‬


‫)‪SELECT CONVERT (char(12), GETDATE(), 103‬‬

‫תוצאת הרצת הקוד‪:‬‬

‫‪12/20/2002‬‬
‫)‪(1 row(s) affected‬‬
‫‪------------‬‬
‫‪20/12/2002‬‬
‫)‪(1 row(s) affected‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪34‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פונקציות שונות‬

‫פונקצית המרה ‪PARSE‬‬

‫פונקציה חדשה לגירסת ‪.sqlserver 2012‬‬

‫זוהי פונקצית המרה המאפשרת להמיר תאריכים טקסטואליים לתאריך תקני של‬
‫‪ .SQL Server‬בדומה לפונקציית ‪ Convert‬ממירה לתבניות תאריך שונות אך אין צורך בפונקציה זאת לזכור‬
‫את קוד תבניות העיצוב‪ ,‬אלא להשתמש בקודי מדינות‪.‬‬

‫מבנה פונקצית ‪PARSE‬‬

‫) ] ‪PARSE ( string_value AS data_type [ USING culture‬‬

‫דוגמה ‪:‬‬
‫בדוגמה הבאה ממירים מחרוזת תאריכית בפורמט אנגליה לטיפוס נתונים תאריך אנגלית ארה"ב‬

‫) '‪SELECT PARSE('31/12/2012' AS DATETIME2 USING 'en-GB‬‬

‫עמוד ‪35‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫הפונקציה ‪ISNULL‬‬

‫פונקציה זו מקבלת עמודה המכילה ‪NULL‬ים וערך להחלפה במקום ה ‪.NULL‬‬


‫שים לב‪:‬‬
‫מבנה פונקצית ‪ISNULL‬‬

‫)‪ISNULL(column_name, value‬‬

‫‪ Column_name‬הוא הביטוי שעלול להיות ‪Null‬‬


‫‪ Value‬הוא הערך בו נרצה להחליף את ה ‪ Null‬אם יופיע‪.‬‬

‫שני הארגומנטים צריכים להיות מאותו טיפוס‪.‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫ומחליפה את‬ ‫הדוגמה הבאה שולפת את העמודות ‪ CompanyName, and Fax‬מטבלת ‪Suppliers‬‬
‫מספרי הפקסים המוצגים כערכים בלתי ידועים (ערכי ‪ )NULL‬במחרוזת‪. Unknown‬‬

‫‪SELECT CompanyName, ISNULL(Fax,'Unknown') AS Fax‬‬


‫‪FROM Suppliers‬‬

‫תוצאת הרצת הקוד‬

‫‪CompanyName‬‬ ‫‪Fax‬‬
‫‪---------------------------‬‬ ‫‪--------------------------‬‬
‫‪Exotic Liquids‬‬ ‫‪Unknown‬‬
‫‪New Orleans Cajun Delights Unknown‬‬
‫‪Grandma Kelly's Homestead (313) 555-3349‬‬
‫‪:‬‬
‫)‪(29 row(s) affected‬‬

‫שים לב יש הבדל בין ‪( ISNULL‬ללא רווח) שהיא פונקציה סקלארית‪ ,‬לבין ‪( IS NULL‬עם רווח) שהוא אופרטור‬
‫של תנאי ‪.WHERE‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪36‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פונקצית ‪CASE‬‬

‫ביטוי המספק אמצעי להחזרת נתונים שונים המבוסס על בדיקת הערך המוחזר‪.‬‬
‫ב‪ SQL-‬קימות שתי ורסיות שונות של ‪ case‬והן‪:‬‬

‫‪Simple CASE expression ‬‬


‫‪Search CASE expression ‬‬

‫ה‪ Simple Case -‬מאפשר בדיקת ערך של משתנה בודד והצגת ערך אחר במקומו‪ .‬דומה ל ‪ Case‬משפות‬
‫תיכנות אחרות‪.‬‬

‫ה‪ Search Case-‬בודק מספר משתנים ומגיב לפי הצורך‪.‬‬

‫‪Simple CASE expression‬‬


‫מבנה‪:‬‬
‫‪CASE input_expression‬‬
‫‪WHEN when_expression THEN result_expression‬‬
‫]‪[...n‬‬
‫[‬
‫‪ELSE else_result_expression‬‬
‫]‬
‫‪END‬‬

‫‪ ‬משפט ה ‪ ELSE‬הוא אופציונאלי‪ .‬אם משמיטם אותו‪ ,‬כל הערכים שלא פורטו יקבלו ‪.NULL‬‬
‫דוגמה ל ‪: SIMPLE CASE‬‬

‫בסיס נתונים‪.Northwind:‬‬
‫הדוגמה הבאה עושה שימוש פשוט בביטוי ‪ CASE‬ומדפיסה תאור עבור הנחה המוגדרת בשאילתה במידה‬
‫והיא קיימת בטבלת פרטי הזמנה‪.‬‬

‫‪SELECT DISTINCT CASE Discount‬‬


‫'‪WHEN 0 THEN 'No Discount‬‬
‫'‪WHEN 0.05 THEN 'Small Discount‬‬
‫'‪ELSE 'Fine Discount‬‬
‫'‪END 'Discount‬‬
‫]‪FROM [Order Details‬‬
‫לאחר הרצת הקוד יתקבל‪:‬‬

‫‪Discount‬‬
‫‪--------------‬‬
‫‪Fine Discount‬‬
‫‪Small Discount‬‬
‫‪No Discount‬‬
‫)‪(3 row(s) affected‬‬

‫עמוד ‪37‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫ אין אפשרות לשלב אי שוויונים‬,‫*שים לב כי ניתן לבדוק יחס של השוואה בלבד מול הערך שבשדה הנבדק‬
Search Case ‫ לשם כך נחוץ‬,simple case -‫במשפט ה‬

.‫ ולאו דווקא שיוויון‬,‫ מאפשר בדיקה מורכבת יותר של ערכים‬Search Case -‫ה‬

Search CASE expression

:‫מבנה‬
CASE
WHEN Boolean_expression THEN result_expression
[...n]
[
ELSE else_result_expression
]
END
.CASE ‫ לא כותבים את שם העמודה הנבדקת מיד לאחר המילה‬Search Case ‫ההבדל במבנה הוא שב‬ 

: SEARCH CASE ‫דוגמה ל‬


.Northwind:‫בסיס נתונים‬
‫ ומחזירה את‬Orders ‫ בטבלת‬RequiredDate -‫ לעומת ה‬ShippedDate -‫הדוגמה הבאה בוחנת את מצב ה‬
.DATEDIFF ‫ההודעה המתאימה המבוססת על פי תוצאות הפונקציה‬

SELECT CustomerID,
CASE
WHEN ShippedDate IS NULL
THEN 'Call for schedule shipping'
WHEN DATEDIFF(dd,ShippedDate,RequiredDate) < 0
THEN 'Call and apologize'
ELSE 'Shipped O.K'
END AS 'Shipping Status'
FROM Orders

‫תוצאת הרצת הקוד‬


CustomerID Shipping Status
---------- --------------------------
VINET Shiped O.K
TOMSP Shiped O.K
:
FOLKO Call for apologizing
BLONP Shiped O.K
:
BONAP Call for schedule shipping
RATTC Call for schedule shipping

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 38 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫פונקציית ‪ISNUMERIC‬‬

‫פונקציה זו מאפשר לנו לבדוק האם ערך מסויים אשר התקבל בפונקציה זו כפרמטר הינו מספרי ( או יכול‬
‫לשמש כערך מספרי )‪.‬‬
‫הערכים שפונצקיה זו מחזירה הם ‪( 1‬יכול לשמש כערך מספרי) ו ‪( 0 -‬לא יכול לשמש כערך מספרי)‬

‫;‪SELECT ISNUMERIC('SQL') AS isnmumeric_result‬‬


‫תחזיר ‪0‬‬

‫;‪SELECT ISNUMERIC(‘101.99') AS isnmumeric_result‬‬


‫תחזיר ‪1‬‬

‫פונקציית ‪IIF‬‬

‫מבנה הפונקציה‬

‫‪SELECT IIF(<Boolean expression> ,<value_if_TRUE>,‬‬


‫;)‪<value_if_FALSE_or_UNKNOWN‬‬

‫בדומה לפונקציית ה ‪ CASE‬גם פונקציה זו מאפשר לנו לבדוק ערכים עפ"י תנאים מוגדרים מראש‪ ,‬למשל ‪:‬‬

‫‪SELECT productid, unitprice,‬‬


‫‪IIF(unitprice > 50, 'high','low') AS pricepoint‬‬
‫;‪FROM Products‬‬

‫פונקציה זו בודקת את מחירו את מוצר מסויים בהתאם לתנאי האם הוא נמוך \ גבוה מ ‪50 -‬‬
‫ומחזירה תוצאות בהתאם‪.‬‬

‫עמוד ‪39‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
CHOOSE ‫פונקציית‬

‫ לדוגמא‬,‫פונקציה זו מחזירה את את הערך המצויין כאינדקס מתוך רשימת ערכים‬

SELECT CHOOSE (3, 'Beverages', 'Condiments', 'Confections') AS choose_result;

)‫ (הערך השלישי‬Confections - ‫במקרה זו יוחזר הערך‬

SELECT employeeid, lastname, reportsto,


choose(reportsto,'1','fuller','3','4','buchanan '(
FROM employees

SELECT productid, productname , categoryid,


CHOOSE (categoryid,
(select categoryname from categories where categoryid = 1),
(select categoryname from categories where categoryid = 2),
(select categoryname from categories where categoryid = 3),
(select categoryname from categories where categoryid = 4),
(select categoryname from categories where categoryid = 5),
(select categoryname from categories where categoryid = 6),
(select categoryname from categories where categoryid = 7),
(select categoryname from categories where categoryid = 8))
FROM products

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 40 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
SQL Server Data Types - 4 ‫פרק‬

Numeric Data Types

Data Type Range Storage (bytes)

tinyint 0 to 255 1

smallint -32,768 to 32,768 2

31
int 2 (-2,147,483,648) to 4
31
2 -1 (2,147,483,647)
63 63
bigint -2 - 2 -1 8
(+/- 9 quintillion)
bit 1, 0 or NULL 1

38 38
decimal/numeric -10 +1 through 10 – 1 when maximum 5-17
precision is used
money -922,337,203,685,477.5808 to 8
922,337,203,685,477.5807
smallmoney -214,748.3648 to 214,748.3647 4

Date and Time Data Types

Data Type Storage Accuracy Recommended Entry Format


(bytes)

datetime 8 Rounded to increments of YYYYMMDD hh:mm:ss[.mmm]


.000, .003, or .007 seconds

smalldatetime 4 1 minute YYYYMMDD hh:mm:ss[.mmm]

datetime2 6 to 8 100 nanoseconds YYYYMMDD hh:mm:ss[.nnnnnnn]


date 3 1 day YYYY-MM-DD
time 3 to 5 100 nanoseconds hh:mm:ss[.nnnnnnn]
datetimeoffset 8 to 10 100 nanoseconds YYYY-MM-DDThh:mm:ss[.nnnnnnn][{+|-
}hh:mm]

41 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
Character Data Types

Data Type Range Storage (bytes)

char(n) 1-8000 characters n bytes, padded


nchar(n) 1-4000 characters 2*n bytes, padded

varchar(n) 1-8000 characters Actual length + 2 bytes

nvarchar(n) 1-4000 characters Actual length + 2 bytes


varchar(max) Up to 2 GB Actual length + 2 bytes
nvarchar(max) Up to 2 GB Actual length + 2 bytes

Other Data Types


Approximate Numerics
float- Floating precision number data from -1.79E + 308 through 1.79E + 308 .
real- Floating precision number data from -3.40E + 38 through 3.40E + 38 .

Binary Strings
binary- Fixed-length binary data with a maximum length of 8,000 bytes .
varbinary- Variable-length binary data with a maximum length of 8,000 bytes .
image- Variable-length binary data with a maximum length of 2^31 - 1 (2,147,483,647) bytes .
Synonyms
Data type synonyms are included for SQL-92 compatibility .
Synonym Mapped to system data type
binary varying varbinary
char varying varchar
character char
character char(1(
character( n ) char( n (
character varying( n ) varchar( n(
dec decimal
double precision float
float [ ( n ) ] for n = 1-7 real
float [ ( n ) ] for n = 8-15 float
integer int
national character( n ) nchar( n (
national char( n ) nchar( n (
national character varying( n ) nva0rchar( n)
national char varying( n ) nvarchar( n )
national text ntext
numeric decimal

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 42 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫פרק ‪ - 5‬שילוב מידע ממספר טבלאות (‪)JOIN‬‬
‫עד עתה עסקנו בשאילתות ששלפו רשומות מטבלה אחת בלבד‪ .‬דהיינו פסוקית ה ‪ From‬הכילה פניה לטבלה‬
‫בודדת‪.‬‬
‫קיימות שאילתות המאפשרות שילוב מידע ממספר טבלאות‪ .‬שאילתות אלו נקראות שאילתות ‪=( Join‬שילוב)‪,‬‬
‫שכן הן משלבות מידע ממספר טבלאות‪ .‬השילוב מתבצע על סמך הקשרים הלוגים המוגדרים בין הטבלאות‬
‫השונות‪.‬‬

‫קיימים שני סינטקסים לשילוב מידע ממספר טבלאות‪:‬‬


‫‪ –ANSI SQL-92‬הטבלאות מוצלבות באמצעות ‪/JOIN….ON‬‬
‫‪ – ANSI SQL -89‬השיטה הישנה להצלבת טבלאות באמצעות פסיקים ‪. WHERE‬‬

‫‪- ANSI SQL-92‬המבנה הכללי של שאילתת ‪: Join‬‬

‫‪SELECT Column list‬‬


‫]‪FROM tbl1 [alias] [join type] JOIN tbl2 [alias‬‬
‫‪ON Join Criteria‬‬

‫]‪[Join Type‬‬
‫קיימים שני סוגי ‪ JOIN‬עיקריים שידונו להלן‪ INNER JOIN :‬ו‪.OUTER JOIN -‬‬

‫]‪[alias‬‬
‫נתחיל עם קצת רקע‪ :‬לכל טבלה במסד נתונים יש שם יחידני המוגדר בעת יצירתה‪ .‬לעיתים שם זה הוא ארוך‬
‫ומסורבל‪ ,‬ולכן‪ -‬כדי לשפר את הקריאות‪ ,‬ניתן לקבוע שם חלופי ( כינוי – ‪ )alias‬לטבלה במקום שמה האמיתי‪,‬‬
‫בדיוק כפי שביצענו עבור עמודות‪( .‬חשוב לזכור כי ה‪ Aliases -‬תקפים רק בפקודת ה‪ select -‬אשר יצרה‬
‫אותם)‪.‬‬

‫על מנת ליצור ‪ alias‬לטבלה מה שנדרש הוא להוסיף את שם הקיצור לאחר ציון שם הטבלה בתת פסוקית‬
‫‪ .From‬מקובל לעשות שימוש באות הראשונה של שם הטבלה כ ‪.Alias -‬‬

‫ועכשיו מה הקשר של כל זה לשאילתות ‪? Join‬‬


‫כאשר פונים לשדה ששמו זהה בשתי הטבלאות השונות חובה לציין לפני הפניה לשדה את שם הטבלה אליה‬
‫הוא שייך (כדי שהשרת יבין לאיזה משני השדות מתכוונים)‪ .‬ניתן לעשות זאת ע"י ציון שמה המלא של הטבלה‬
‫לפני שם העמודה‪( ,‬למשל‪ )Products.CategoryID :‬או שניתן להסתפק ב ‪ Alias -‬של הטבלה‪.‬‬
‫(‪ .)p.CategoryID‬מקובל לעשות שימוש ב‪ Allias -‬מטעמי נוחות וקריאות של הקוד‪.‬‬

‫בנוסף‪ ,‬רצוי לציין תמיד את שם הטבלה לפני שם העמודה‪ ,‬שכן תהליך זה מקל על ביצועי השרת בעת השליפה‬
‫עצמה‪ ,‬וגם הופך את השאילתא לקריאה יותר‪.‬‬

‫לכן קל יותר לעבוד עם כינויים לטבלאות‪ ,‬ולא עם שמותיהן המלאים‪.‬‬

‫סעיף ה ‪ On -‬מגדיר את הקריטריון לשילוב מידע משתי הטבלאות‪.‬‬


‫פקודת ‪ join‬יוצרת מכפלה קרטזית בין הטבלאות ‪ -‬במקרה של שתי טבלאות כל שורה של טבלה אחת תצורף‬
‫לכל אחת מהשורות של הטבלה השניה‪ .‬מרחב השליפה יכלול ‪ M*N‬תוצאות כאשר ‪ N‬הינו מספר השורות‬
‫בטבלה אחת ו‪ M -‬הינו מספר השורות בטבלה השניה‪ .‬לרוב‪ ,‬לתוצאה המתקבלת ממכפלה קרטזית אין ערך‬
‫של ממש בגלל עומס הנתונים הלא רלוונטיים‪ ,‬לפיכך יש לצרף תנאי לשילוב מידע משתי הטבלאות‪.‬‬
‫עמוד ‪43‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬
‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫ברוב המקרים הקריטריון לשידוך רשומות מתאימות משתי טבלאות יהיה מבוסס על עמודה משותפת המופיעה‬
‫בשתי הטבלאות‪ .‬ברוב המקרים העמודה המשותפת היא העמודה עליה מבוסס קשר ה ‪ PK -‬ו ‪ FK -‬בין שתי‬
‫הטבלאות‪.‬‬

‫בדרך כלל‪ ,‬כאשר ‪ JOIN‬מתבסס על קשר ‪ ,PK-FK‬יופיע הסימן שווה במשפט ה ‪ .ON‬יחד עם זאת‪ ,‬ניתן‪ ,‬אם‬
‫רוצים‪ ,‬לשלב מידע בין טבלאות על סמך קשר לוגי אחר‪ ,‬ומותר להשתמש במשפט ה‪ ON -‬בכל האופרטורים‬
‫המוכרים‪ ,‬וכן ב ‪ AND/OR‬אם יש צורך‪.‬‬

‫מבנה משפט ה ‪ ON‬מזכיר מאוד מבנה של משפט ‪ ,WHERE‬אלא שבמשפט ה‪ ON-‬יש לכתוב את התנאים‬
‫לפיהם יש לחבר את הטבלאות‪ ,‬ובמשפט ה ‪ WHERE‬את שאר התנאים ‪.‬‬

‫‪INNER Join‬‬

‫זהו ה‪ JOIN-‬הבסיסי ביותר‪ ,‬והוא משמש כאמור על מנת לשלב מידע משתי טבלאות (בדרך כלל‪,‬בהסתמך על‬
‫קשר ‪.)PK-FK‬‬
‫לדוגמה‪ :‬אם נרצה לשלוף רשימה של שמות המוצרים מטבלת ‪ Products‬ולכל מוצר נרצה לשדך את שם‬
‫הקטגוריה אליה הוא שייך (מידע הנמצא בטבלת ‪ )Categories‬נדרש לעשות שימוש בפעולת ה ‪ Join -‬ולשדך‬
‫רשומות מתאימות מטבלאות ‪ Products‬ו ‪.Categories -‬‬
‫השאילתה המתאימה תראה כך‪:‬‬

‫‪SELECT p.ProductName, c.CategoryName‬‬


‫‪FROM Products p INNER JOINCategories c‬‬
‫‪On p.CategoryID = c.CategoryID‬‬

‫בדוגמה לעיל‪ ,‬השרת יסרוק את הרשומות בטבלת ‪ Products‬ועבור כל מוצר יחפש את הרשומה המתאימה‬
‫לו בטבלת ‪ .Categories‬הקריטריון על פיו יחליט השרת מי היא הרשומה המתאימה מופיע בסעיף ה ‪,ON -‬‬
‫ומבוסס על השוואת הערך המופיע בעמודה ‪ CategoryID‬בטבלת ‪( Products‬עמודת "בת" עליה מוגדר‬
‫‪ (Foreign Key‬עם הערך המופיע בעמודת ‪ CategoryID‬בטבלת ‪( Categories‬עמודת "אם" עליה מוגדר‬
‫‪)Primary Key‬‬

‫שים לב המילה ‪ INNER‬היא אופציונאלית‪ .‬כלומר‪ ,‬אפשר להשמיטה ממשפט ה ‪ FROM‬ולקבל את אותה‬
‫תוצאה בדיוק‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪44‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
:WHERE ‫דוגמה לשימוש בתנאי‬

.Northwind:‫בסיס נתונים‬
‫ עבור כל הזמנה מצוין שם‬.‫ פריטים מאותו מוצר‬9 ‫הדוגמה מציגה פרטי רשומות הזמנה אשר הוזמנו בהן‬
.‫ הנתונים ממוינים ע"פ מחיר עלות המוצר‬.‫ מחיר המוצר ליחידה וכמות הפריטים‬,‫המוצר‬

SELECT P.ProductName, O.UnitPrice, O.Quantity


FROM Products P JOIN [Order Details] O
ON O.ProductID = P.ProductID
where Quantity = 9
ORDER BY O.UnitPrice

:‫תוצאת הרצת השאילתה‬

ProductName UnitPrice Quantity


----- --------------------- --------------------- ----------------------------------------
Filo Mix 7.0000 9
Jack's New England Clam Chowder 9.6500 9
Jack's New England Clam Chowder 9.6500 9
:
:
30(row(s) affected)
‫ טבלאות‬2 - ‫שילוב יותר מ‬

:‫ המבנה הכללי יראה כך‬.‫ יותר מצמד טבלאות‬join ‫ניתן לשלב בשאילתת‬

SELECT Column list


FROM tbl1 [alias] [join type] JOIN tbl2 [alias]
ON Join Criteria
JOIN tbl3 [alias]
ON Join Criteria

: ‫דוגמה‬
.Northwind:‫בסיס נתונים‬
‫ כאשר עבור כל מוצר מצוין שם הקטגוריה שלו ושם החברה‬,products ‫הצגת שמות המוצרים מטבלת‬
. ‫המספקת את המוצר‬

Select c.CategoryName , p.ProductName , s. CompanyName


From Categories c Join Products p
On c .CategoryId= p. CategoryId
Join Suppliers s
On s.SupplierID=p. SupplierID

45 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫‪Outer join‬‬

‫שאילתה המחזירה את כל הנתונים מטבלה אחת ואת המשלימים לה מהטבלה האחרת‪.‬‬


‫בתוצאה של שאילתת ‪ join‬רגילה מופיעות אך ורק רשימות המקיימות את התנאי‪ .‬לדוגמה‪ ,‬אם הגדרנו‬
‫שאילתת ‪ join‬בין מחלקות לעובדים ויש מחלקה שאין לה עובדים היא לא תופיע בתוצאה‪.‬‬
‫בכדי להציג את כל הרשומות‪ ,‬כולל אלו שהוחסרו ב‪ join -‬הרגיל‪ ,‬נשתמש ב‪.outer join -‬‬
‫כיוון התנאי ב‪ outer join -‬קובע את הטבלה ממנה ילקחו כל הרשומות כולל אלו שאינן עונות על תנאי הקישור‬
‫בין הטבלאות‪ .‬רשומות להן אין רשומה מתאימה בטבלה השניה יופיעו בתוצאה עם ערכי ‪ Null‬תחת העמודות‬
‫השייכות לטבלה השניה‪.‬‬

‫יש שלושה תתי סוגים של ‪ Right ,Left :Outer Join‬ו ‪Full‬‬

‫ב ‪ Left Outer Join -‬השרת יחזיר את כל הרשומות מהטבלה השמאלית בסעיף ה ‪ From -‬ורק את‬ ‫‪‬‬
‫הרשומות המתאימות להן מהטבלה הימנית בסעיף ה ‪.From‬‬

‫לדוגמה‪ :‬ב ‪ Join -‬של טבלאות ‪ Customers‬ו ‪ Orders -‬כאשר טבלת ‪Customers‬מופיעה בתור הטבלה‬
‫השמאלית‪:‬‬
‫‪From Customers Left Outer Join Orders‬‬

‫נקבל את כל הרשומות מטבלת ‪( . Customers‬נקבל גם לקוחות שלא ביצעו הזמנות ולכן אין להם רשומות‬
‫מתאימות בטבלת ‪ .)Orders‬מטבלת ‪ Orders‬נקבל רק הזמנות שבוצעו ע"י לקוחות שמופיעים בטבלת‬
‫‪ .Customers‬עבור לקוחות שלא ביצעו הזמנות נקבל ערכי ‪ Null‬תחת העמודות שנשלפות מטבלת ‪.Orders‬‬
‫‪ ‬ב‪ Right Outer Join -‬העקרון דומה אלא שהפעם השרת יחזיר את כל הרשומות מהטבלה‬
‫שמופיעה בצד ימין של סעיף ה ‪.From‬‬

‫ב‪ FullOuter Join -‬השרת יחזיר את כל הרשומות משתי הטבלאות‪( .‬ישדך רשומות להן יש רשומה‬ ‫‪‬‬
‫מתאימה בטבלה השניה)‪ .‬רשומות להן אי ן רשומה מתאימה בטבלה השניה יופיעו בתוצאה עם ערכי‬
‫‪ Null‬תחת העמודות השייכות לטבלה השניה‪.‬‬

‫דוגמה‪:‬‬

‫בסיס נתונים‪.Northwind:‬‬
‫הצגת שמות כל הלקוחות מטבלת ‪ customers‬ליד כל לקוח שיש לו הזמנה נציין את מספרה (יכול להיות לקוח‬
‫שרשום במאגר אך ברגע זה אין לו הזמנה)‪.‬‬

‫‪select c.customerid,o.orderid‬‬
‫‪from customers c left join orders o‬‬
‫‪on c.customerid=o.customerid‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪46‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫התוצאה שתתקבל מהרצת הקוד‪:‬‬
‫‪customerid orderid‬‬
‫‪----------- ----------‬‬
‫‪ALFKI‬‬ ‫‪10643‬‬
‫‪ALFKI‬‬ ‫‪10692‬‬
‫‪:‬‬
‫)‪832(row(s) affected‬‬

‫לעומת זאת‪ ,‬אילו היינו מריצים ‪ join‬רגיל‪:‬‬


‫‪select c.customerid,o.orderid‬‬
‫‪from customers c inner join orders o‬‬
‫‪on c.customerid=o.customerid‬‬
‫היינו מקבלים‪:‬‬
‫)‪830(row(s) affected‬‬

‫וכנ"ל בהרצת ‪ ,right join‬שכן לא יכולה להיות הזמנה שאינה משויכת ללקוח‪.‬‬

‫‪select c.customerid,o.orderid‬‬
‫‪from customers c right join orders o‬‬
‫‪on c.customerid=o.customerid‬‬

‫התוצאה‪:‬‬
‫)‪830row(s) affected‬‬

‫‪Cross join‬‬

‫זהו ‪ Join‬אשר מציג תוצאות של כל הצירופים האפשריים בין השורות של שתי הטבלאות‪.‬כלומר כל רשומה‬
‫מהטבלה הראשונה תהיה משולבת עם כל רשומה מהטבלה השנייה‪.‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים ‪Northwind‬‬
‫נסיון להציג את העובדים עם הטריטוריה שלהם‪ .‬התוצאה שהתקבלה‪ ,‬כל עובד מטבלת ‪ Employees‬משולב‬
‫עם כל טריטוריה מטבלת ‪.EmployeesTerritories‬‬
‫* ‪SELECT‬‬
‫‪FROM EmployeeTerritories cross join employees‬‬

‫התוצאה תהיה‪:‬‬
‫אם יש ‪ 9‬עובדים ו‪ 49 -‬טריטוריות המכפלה שלהם תציג את השליפה הבאה‪.‬‬

‫)‪441row(s) affected‬‬

‫עמוד ‪47‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Self join‬‬

‫לעיתים קיים צורך לבצע צירוף של רשימות מטבלה לרשימות מאותה טבלה ‪ -‬מהלך הנקרא ‪reflexive join‬‬
‫או ‪.self join‬‬
‫‪ Self Join‬הוא ‪ Join‬מיוחד מעט מבחינה לוגית‪ ,‬אבל מבחינת סינטקס הוא מבוסס על מה שנלמד עד כה‪.‬‬

‫שפת ‪ SQL‬מאפשרת לפנות מספר פעמים אל אותה הטבלה במשפט ‪ select‬כאילו הפניה נעשתה למספר‬
‫טבלאות שונות‪ .‬היכולת להתיחס אל הטבלאות כאל שונות היא ע"י מתן ‪ aliases‬שונים במשפט ה‪from -‬‬
‫לטבלה עליה מתבצעת פעולת ה‪( self join -‬מעבר לכך פעולת הכתיבה רגילה)‪.‬‬

‫לדוגמה‪ :‬נניח כי היתה לנו טבלת עובדים אשר עבור כל עובד בין שאר הנתונים היה נשמר עבורו שמו ‪,‬מספר‬
‫העובד שלו ומספר העובד של המנהל שלו‪ ,‬אילו היינו רוצים להדפיס את שמות העובדים ושמות מנהליהם היינו‬
‫צריכים לפנות פעמיים לאותה טבלה פעם אחת עבור לקיחת שמות העובדים ופעם שניה עבור לקיחת שמות‬
‫המנהלים שהם כמובן גם כן עובדים ולכן יופיעו באותה הטבלה ‪ -‬במקרה מסוג זה היינו משתמשים ב‪self -‬‬
‫‪.join‬‬

‫דוגמה מספר ‪: 6‬‬


‫בסיס נתונים‪.Northwind:‬‬
‫הצגת שמות העובדים ושמות האנשים שהם מדווחים להם‪:‬‬

‫‪Select w.LastName+’ ‘+w.FirstName as "worker” ,‬‬


‫”‪r.LastName+’ ‘+r.FirstName as “Reports To‬‬
‫‪from Employees w join Employees r‬‬
‫‪On w. ReportsTo=r.EmployeeId‬‬

‫תוצאת הרצת הקוד‬


‫‪worker‬‬ ‫‪Reports To‬‬
‫‪-------------------------------- --------------------------------‬‬
‫‪Davolio Nancy‬‬ ‫‪Fuller Andrew‬‬
‫‪Leverling Janet‬‬ ‫‪Fuller Andrew‬‬
‫‪Peacock Margaret‬‬ ‫‪Fuller Andrew‬‬
‫‪Buchanan Steven‬‬ ‫‪Fuller Andrew‬‬
‫‪Suyama Michael‬‬ ‫‪Buchanan Steven‬‬
‫‪King Robert‬‬ ‫‪Buchanan Steven‬‬
‫‪Callahan Laura‬‬ ‫‪Fuller Andrew‬‬
‫‪Dodsworth Anne‬‬ ‫‪Buchanan Steven‬‬

‫)‪( 8 row(s) affected‬‬

‫שים לב‪ ,‬שעובדים שלא מדווחים לאף אחד ‪ -‬לא התקבלו ‪ ,‬כדי להציגם יש להשתמש ב ‪.Outer join‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪48‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪ - ANSI SQL-89‬שימוש בפסיק ו‪WHERE -‬‬

‫זהו סינטקס אשר היה מקובל לשימוש לפני גירסת ‪ .ANSI SQL 92‬הרעיון כמו ב‪ , JOIN -‬לייבא מידע‬
‫ממספר טבלאות אך במקום השימוש במילה ‪ JOIN‬נשתמש בפסיק כדי להפריד בין הטבלאות‪ ,‬ובמקום‬
‫המילה ‪ ON‬נציין את הקשר בין הטבלאות באמצעות המילה ‪.WHERE‬‬

‫פקודת ה‪ INNER JOIN -‬תיראה כך‪:‬‬

‫‪SELECT Column list‬‬


‫‪FROM tbl1 [alias], tbl2 [alias], tbl3 [alias],….‬‬
‫‪WHERE criteria‬‬
‫‪AND conditions‬‬

‫דוגמה ‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הצגת שמות המוצרים מטבלת ‪ ,products‬כאשר עבור כל מוצר מצוין שם הקטגוריה שלו ושם החברה‬
‫המספקת את המוצר ‪.‬‬

‫‪SELECT c.CategoryName , p.ProductName , s. CompanyName‬‬


‫‪FROM Categories c , Products p , Suppliers s‬‬
‫‪WHERE c .CategoryId= p. CategoryId‬‬
‫‪AND s.SupplierID=p. SupplierID‬‬
‫'‪AND AND productname LIKE '%a%‬‬

‫פקודת ה‪ CROSS JOIN -‬תיראה כך‪:‬‬


‫התוצאה תהיה כמו בגירסת ‪ ,Ansi sql-92‬כל הצירופים האפשריים משילוב של רשומות בין שתי טבלאות‪.‬‬

‫‪SELECT Column list‬‬


‫]‪FROM tbl1 [alias], tbl2 [alias‬‬

‫עמוד ‪49‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪Group Function And Grouping Sets - 6‬‬
‫‪ - Group Function‬ה ינן פונקציות המופעלות על מספר רשומות ומחזירות ערך בודד‪.‬‬

‫לדוגמה‪ :‬פונקצית ‪ - Max‬פ ונקציה המקבלת מספר ערכים מרשומות שונות ומחזירה את הערך המקסימלי‬
‫שביניהן‪.‬‬

‫סוגי ‪:Group Function‬‬

‫פונקציות מספריות‪:‬‬
‫‪ - Avg‬מחזירה את ממוצע כל הערכים בקבוצה שהם לא ‪.NULL‬‬ ‫‪‬‬
‫‪ - Sum‬סוכמת את מספר הפריטים בקבוצה‪.‬‬ ‫‪‬‬

‫פונקציות מספריות‪ ,‬תאריכיות ומחרוזתיות‪:‬‬


‫‪ - Count‬מחזירה את מספר הפריטים בקבוצה‪.‬‬ ‫‪‬‬
‫‪ - Max‬מחזירה את הערך הגבוה ביותר מבין הקבוצה‪.‬‬ ‫‪‬‬
‫‪ - Min‬מחזירה את הערך הנמוך ביותר מבין הקבוצה‪.‬‬ ‫‪‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הצגת ממוצע המחירים של המוצרים בטבלת ‪.products‬‬

‫)‪SELECT avg(UnitPrice‬‬
‫‪FROM Products‬‬
‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הצגת מספר העובדים שגרים בעיר ‪.London‬‬

‫)*(‪SELECT count‬‬
‫‪FROM Employees‬‬
‫'‪WHERE city='London‬‬
‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הצגת מספר הלקוחות שביצעו הזמנה (אותו לקוח שביצע מספר הזמנות יספר פעם אחת בלבד)‪.‬‬

‫"‪SELECT count(Distinct CustomerId) as "num of customers‬‬


‫‪FROM Orders‬‬

‫שים לב כי ‪ Group Function‬מתעלמות מערכי ‪ Null‬כך שעלולות להתקבל תוצאות לא מדויקות אם לא נטפל‬
‫במקרים אלו‪ ,‬לדוגמה בחישוב ממוצע‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪50‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫שימוש ב‪Group By -‬‬

‫כאשר משתמשים ב‪ Group Function -‬ניתן לחלק את קבוצת הרשומות שעליה מבוצעת הפונקציה למספר‬
‫תתי קבוצות‪ ,‬כך שהפונקציה תופעל על כל תת קבוצה בנפרד‪.‬‬
‫ההפרדה לתתי קבוצות מתבצעת ע"י הוספת משפט ה ‪ GROUP BY‬למשפט ה‪ SELECT -‬בתוספת ציון‬
‫העמודה על פיה תתבצע החלוקה לתתי הקבוצות‪.‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הצגת שמות הערים ומספר העובדים שגרים בכל אחת מהן על פי הנתונים שבטבלת ‪.Employees‬‬

‫‪SELECT count(*) as "num of employees",city‬‬


‫‪FROM Employees‬‬
‫‪GROUP BY City‬‬

‫התוצאה שתתקבל לאחר הרצת הקוד‪:‬‬


‫‪City‬‬ ‫‪num of employees‬‬
‫‪---------------‬‬ ‫‪---------------‬‬
‫‪Kirkland‬‬ ‫‪1‬‬
‫‪London‬‬ ‫‪4‬‬
‫‪Redmond‬‬ ‫‪1‬‬
‫‪Seattle‬‬ ‫‪2‬‬
‫‪Tacoma‬‬ ‫‪1‬‬

‫( ‪) 5 row(s) affected‬‬

‫*ניתן להגדיר תת קבוצה לתת קבוצה ע"י סימון פסיק לאחר שם העמודה וציון שם עמודה נוספת‪ ,‬שתהווה‬
‫בסיס למיון המשני‪.‬‬

‫שים לב‪:‬‬

‫‪ .1‬כל עמודה אשר מופיעה במשפט ה ‪ SELECT‬ולא מופעלת עליה פונקציה קבוצתית‪ ,‬חייבת להופיע‬
‫במשפט ה ‪.GROUP BY‬‬

‫‪ .2‬ב‪ SQL Server -‬אסור לבצע קינון של ‪( group function‬אך קיימות סביבות אחרות המאפשרות‬
‫זאת)‪ .‬לדוגמה‪:‬‬

‫‪SELECT max(avg(unitprice))...‬‬

‫עמוד ‪51‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫שימוש ב‪Having -‬‬

‫לא ניתן להפעיל תנאי במשפט ה ‪ WHERE‬על ערך המוחזר כתוצאה מ‪( Group Function -‬סדר ביצוע‬
‫הפעולות בפועל שונה מסדר הכתיבה) ולכן‪ ,‬כאשר רוצים לבצע התניה על הערך שמחזירה הפונקציה‬
‫הקבוצתית יש לציין את התנאי במשפט ה ‪.HAVING‬‬

‫דוגמה‪:‬‬
‫בסיס הנתונים ‪NorthWind‬‬
‫הצגת שמות הערים שגרים בהן לפחות שני עובדים‪ +‬ציון מספר העובדים ע"פ הנתונים מטבלת ‪.Employees‬‬

‫‪SELECT count(*) AS "num of employee" ,city‬‬


‫‪FROM Employees‬‬
‫‪GROUP BY City‬‬
‫‪HAVING count(*)>=2‬‬
‫התוצאה שתתקבל לאחר הרצת הקוד‪:‬‬

‫‪city‬‬ ‫‪num of employee‬‬


‫‪--------------- ---------------‬‬
‫‪London‬‬ ‫‪4‬‬
‫‪Seattle‬‬ ‫‪2‬‬

‫(‪) 2 row(s) affected‬‬

‫דוגמה מסכמת‪:‬‬

‫הצגת ה‪ id -‬של כל הלקוחות שביצעו יותר מ‪ 5 -‬הזמנות משנת ‪ 1998‬ואילך ‪ +‬ציון מספר ההזמנות‪ .‬הנתונים‬
‫המוחזרים יוצגו במיון אלפא‪-‬ביתי‪.‬‬
‫‪"SELECT customerid,count(*) as "num of order‬‬
‫‪FROM orders‬‬
‫'‪WHERE OrderDate>='01/01/1998‬‬
‫‪GROUP BY CustomerID‬‬
‫‪HAVING count(*)>=5‬‬
‫‪ORDER BY customerid‬‬
‫התוצאה המתקבלת מהרצת הקוד‪:‬‬
‫‪customerid num of orders‬‬
‫‪-------------‬‬ ‫‪---------‬‬
‫‪BERGS‬‬ ‫‪5‬‬
‫‪BONAP‬‬ ‫‪6‬‬
‫‪BOTTM‬‬ ‫‪8‬‬
‫‪ERNSH‬‬ ‫‪9‬‬
‫‪FOLKO‬‬ ‫‪9‬‬
‫‪:‬‬
‫‪:‬‬
‫‪REGGC‬‬ ‫‪5‬‬
‫‪SAVEA‬‬ ‫‪11‬‬
‫‪SUPRD‬‬ ‫‪6‬‬

‫( ‪)17 row(s) affected‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪52‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Logical Query Processing‬‬
‫סדר כתיבה מול סדר ביצועים‪:‬‬

‫בשל סדר ביצועי פעולות המערכת לפקודת ‪ , Select‬לא ניתן להפעיל תנאים על פונקציות קבוצה בשורת‬
‫‪ , where‬מכיוון שהמערכת מבצעת ראשית צמצום רשומות באמצעות שורה זאת‪ ,‬ורק לאחר מכן מקבצת את‬
‫הנתונים לקבוצות משותפות‪ .‬לכן שורת ‪ Having‬הכרחית כאשר מעוניינים להוסיף תנאים על פונקציות קבוצה‪.‬‬

‫עמוד ‪53‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
GROUPING SETS

.‫ מספר הרחבות אשר מאפשרות ליצור סיכומי ביניים בנוסף לחישובים של פונקציות הקבוצה‬GROUP BY-‫ל‬

GROUPING SETS
ROLLUP
CUBE

.Group by ‫ מאפשר ליצור סיכומי ביניים עפ"י קבוצות שונות בשורת‬Grouping set ‫אופרטור‬
:‫מבנה הפקודה‬

SELECT <column list with aggregate(s)>


FROM <source>
GROUP BY
GROUPING SETS(
(<column_name>),--one or more columns
(<column_name>),--one or more columns
() -- empty parentheses if aggregating all rows
);

Group by -‫פקודה הבאה מציגה את מס' הזמנות שביצע כל עובד לכל לקוח באמצעות שימוש בפקודת ה‬
‫ שאילתות‬2 ‫ נאלצנו לכתוב‬,‫ וכדי להציג מס' הזמנות לכל עובד בנפרד ממס' הזמנות לכל לקוח‬,‫הסטנדר טית‬
.‫נפרדות‬
SELECT EmployeeID,customerid, count(*)
FROM orders
WHERE customerid like 'b%'
GROUP BY EmployeeID,customerid
ORDER BY employeeid

‫ תחשב את הסיכום‬Group by -‫ ניתן לקבוע עפ"י איזה קבוצות שורת ה‬Groupin set ‫באמצעות פקודת‬
.‫הכולל‬
SELECT EmployeeID,customerid,year(orderdate), count(*)
FROM orders
WHERE customerid like 'b%'
GROUP BY GROUPING SETS (EmployeeID,customerid,year(orderdate))
ORDER BY employeeid

SELECT EmployeeID,customerid,year(orderdate), count(*)


FROM orders
WHERE customerid like 'b%'
GROUP BY GROUPING SETS
((customerid,year(orderdate)),(employeeid,year(orderdate)),())
order by employeeid

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 54 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫‪CUBE AND ROLLUP‬‬

‫כמו פקודת ה‪ ,Grouping sets-‬גם פקודות ה‪ Rollup & cube -‬מאפשרות ליצור סיכומי ביניים לקבוצות‬
‫מרובות בשילוב עם פונקציות קבוצה‪ .‬בשונה מ‪ Grouping sets -‬אין צורך בפקודות אלה לקבוע את סדר‬
‫הקבוצות‪.‬‬

‫‪ – Rollup‬יוצר קבוצות של סיכומי ביניים עפ"י סדר הנחת העמודות בשורת ה‪.Group by -‬‬

‫מבנה הפקודה‪:‬‬
‫>)‪SELECT <column(s) with aggregate(s‬‬
‫)‪FROM table(s‬‬
‫)…‪GROUP BY ROLLUP (column1, column2,column3,‬‬

‫סיכומי ביניים שיופיעו בתוצאת השליפה ‪:‬‬


‫‪(column1, column2,column3,…) (column1,column2( )column1).‬‬

‫בדוגמה הבאה בנוסף למספר מוצרים המסופקים ע"י ספק בכל קטגוריה ‪ ,‬תופיע שורת מספר כולל של מוצרים‬
‫לכל קטגוריה‪.‬‬

‫)*(‪SELECT categoryid, supplierid, count‬‬


‫‪FROM products‬‬
‫)‪GROUP BY ROLLUP (categoryid, supplierid‬‬

‫‪.Group by‬‬ ‫‪ – Cube‬יוצרת שורת סיכומי ביניים לכל שילוב של קבוצות המוגדרות בשורת ה‪-‬‬

‫מבנה הפקודה‪:‬‬
‫>)‪SELECT <column(s) with aggregate(s‬‬
‫)‪FROM table(s‬‬
‫)…‪GROUP BY cube (column1, column2,column3,‬‬

‫סיכומי ביניים שיופיעו בתוצאת השליפה ‪:‬‬


‫(‪(column1,column2,column3‬‬ ‫)‪)column1,column2()column2,column3‬‬
‫)‪(column1,column3)(column1)(column2)(column3‬‬

‫בדוגמה הבאה בנוסף למספר מוצרים המסופקים ע"י ספק בכל קטגוריה ‪ ,‬תופיע שורת מספר כולל של מוצרים‬
‫לכל קטגוריה ושורת מספר כולל של מוצרים לכל ספק ומספר המוצרים הכללי בכל הטבלה‪.‬‬

‫)*(‪SELECT categoryid, supplierid, count‬‬


‫‪FROM products‬‬
‫)‪GROUP BY CUBE (categoryid, supplierid‬‬

‫עמוד ‪55‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪ - 7‬תתי שאילתות (‪)SUBQUERIES‬‬
‫לעיתים נרצה להציג נתונים מסוימים שניתן להציגם אך ורק ע"י הפעלת תת שאילתה בתוך השאילתה‬
‫הראשית‪.‬‬
‫לדוגמה‪ :‬שם המוצר בעל המחיר המינימלי‪ .‬אנו יודעים כי שימוש ב‪ Group Function -‬מאפשר להציג תוצאות‬
‫של הפונקציות או שדות המופיעים לאחר משפט ה‪ group by -‬ועל כן במקרה כמו זה‪ ,‬היינו רוצים להציג את‬
‫פרטי המוצר שמחירו שווה למחיר המינימלי אשר יחושב בתת שאילתה‪.‬‬

‫בנוסף‪ ,‬כאשר נרצה לשלוף נתונים אליהם נבצע השוואה כלשהי‪ ,‬אך יש צורך קודם למצוא את אותו הערך אליו‬
‫נרצה לבצע את ההשוואה‪.‬‬
‫לדוגמה‪ :‬מציאת כל המוצרים אשר מחירם גדול ממחירו של המוצר ’‪ ,‘Chai‬קודם עלינו למצוא מה הוא מחירו‬
‫של המוצר '‪ 'Chai‬ורק אחר כך לבצע את ההשוואה‪.‬‬

‫מספר עובדות על שימוש בתת שאילתות‪:‬‬

‫השאילתה הראשית תקרא ‪ Main Query‬כאשר תתי השאילתות יקראו ‪.Sub - Query‬‬ ‫‪‬‬
‫ניתן לכתוב מספר תתי שאילתות עבור שאילתה ראשית אחת‪.‬‬ ‫‪‬‬
‫ניתן לשלב תת שאילתה אחרי‪ Having ,Where :‬ו‪.From-‬‬ ‫‪‬‬
‫התת שאילתה תמיד מורצת לפני השאילתה הראשית‪.‬‬ ‫‪‬‬
‫תת שאילתה תיכתב בסוגריים‪.‬‬ ‫‪‬‬
‫תת שאילתה תופיע בצד הימני של אופרטור ההשוואה‪.‬‬ ‫‪‬‬
‫אין להשתמש במשפט ‪ order by‬בתת שאילתה ‪.‬‬ ‫‪‬‬
‫תת השאילתה תחזיר עמודה אחת אליה תבוצע ההשוואה (בבסיסי נתונים שונים מ‪ SQL Server -‬קיימת‬ ‫‪‬‬
‫אפשרות שהתת שאילתה תחזיר יותר מעמודה אחת)‪.‬‬
‫תת השאילתא תחזיר ערך מאותו ה ‪ DATA TYPE‬של העמודה אליה היא מושוות בשאילתא החיצונית‪.‬‬ ‫‪‬‬
‫תת השאילתה חייבת להחזיר מספר ערכים בהתאם לאופרטור אליו היא מושוות בשאילתה החיצונית‪.‬‬ ‫‪‬‬

‫שני סוגים של תת שאילתה‪:‬‬


‫‪Single row subquery‬‬

‫‪ ‬תת שאילתה המחזירה ערך בודד‪ .‬האופרטורים לשאילתא מסוג זה הינם‪>= ,> ,<= ,< ,>< ,= :‬‬
‫דוגמה ל‪:single row subquery -‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הצגת המחירים ושמות המוצר בעלי עלות גבוהה מזו של מוצר מספר ‪ 2‬מטבלת ‪products‬‬

‫‪SELECT ProductName, UnitPrice‬‬


‫‪FROM Products‬‬
‫‪WHERE UnitPrice>(SELECT UnitPric‬‬
‫‪FROM Products‬‬
‫)‪WHERE productid = 2‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪56‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Multiple row subquery‬‬

‫‪ ‬שאילתה המחזירה יותר מערך בודד‪ .‬האופרטורים לשאילתא מסוג זה הינם‪ALL ,ANY ,NOT IN ,IN :‬‬
‫‪ - IN‬נשתמש בו כאשר נרצה לבצע השוואה מול אחד מהערכים שחזרו מתת השאילתה (ההתנהגות זהה‬
‫להתנהגות אופרטור ‪ IN‬בתת משפט ‪.)where‬‬

‫‪ – NOT IN‬ההפך מ ‪ .IN‬שונה מכל אחד מהערכים שמחזירה תת השאילתא‪.‬‬

‫‪ - All‬נשתמש בו כאשר נרצה שהערך הנבדק יושווה ויקיים את התנאי מול ערכי המינימום והמקסימום שיחזרו‬
‫מתת השאילתה‪.‬‬
‫‪ - <ALL‬גדול מערך מקסימלי שמחזירה תת השאילתא‪.‬‬
‫‪ - > ALL‬קטן מהערך המינימלי שמחזירה תת השאילתא‪.‬‬

‫‪ - Any‬נשתמש בו כאשר נרצה שהערך הנבדק יושווה ויקיים את התנאי מול ערכי המינימום והמקסימום שיחזרו‬
‫מתת השאילתה‪.‬‬
‫‪ - <ANY‬גדול מהערך המינימלי שמחזירה תת השאילתא‪.‬‬
‫‪ - >ANY‬קטן מהערך המקסימלי שמחזירה תת השאילתי‪.‬‬

‫דוגמה ל‪: IN-‬‬


‫בסיס הנתונים ‪:NorthWind‬‬
‫דוגמה זו מחזירה את ה‪ id -‬ושמות המוצרים אשר הוזמנו מהם יותר מ‪ 1200-‬פריטים‪.‬‬

‫‪SELECT ProductID,ProductName‬‬
‫‪FROM products‬‬
‫‪WHERE ProductID IN(SELECT ProductID‬‬
‫]‪FROM [order details‬‬
‫‪GROUP BY ProductID‬‬
‫)‪HAVING sum(Quantity )>1200‬‬

‫התוצאה המתקבלת מהרצת הקוד‪:‬‬

‫‪ProductID ProductName‬‬
‫‪---------------------------------------- -----------‬‬
‫‪59 Raclette Courdavault‬‬
‫‪56 Gnocchi di nonna Alice‬‬
‫‪60 Camembert Pierrot‬‬
‫‪31 Gorgonzola Telino‬‬

‫(‪)row(s) affected 4‬‬

‫עמוד ‪57‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫דוגמה ל‪:ALL -‬‬
‫בסיס נתונים ‪NorthWind‬‬
‫דוגמה זו מחזירה את פרטי המוצרים אשר מחירם מעל הערך המקסימלי שהחזירה תת השאילתא (תת‬
‫השאילתא מחזירה את מחירי המוצרים בקטגוריה מספר ‪.)7‬‬

‫‪SELECT productid, productname, unitprice‬‬


‫‪FROM products‬‬
‫‪WHERE unitprice > ALL (SELECT unitprice‬‬
‫‪FROM products‬‬
‫)‪WHERE categoryid = 7‬‬

‫תת השאילתא מחזירה את הערכים הבאים‪:‬‬


‫‪Unitprice‬‬
‫‪---------------‬‬

‫‪30.00‬‬
‫‪23.25‬‬
‫‪45.60‬‬
‫‪53.00‬‬
‫‪10.00‬‬

‫תוצאת הרצת הקוד‪:‬‬


‫יופיעו כל המוצרים אשר מחירם גדול מהמחיר המקסימלי שהחזירה תת השאילתא שהוא מחיר ‪: 53.00‬‬

‫‪Productid‬‬ ‫‪productname‬‬ ‫‪unitprice‬‬


‫‪-------------‬‬ ‫‪------------------------‬‬ ‫‪-----------------‬‬
‫‪9‬‬ ‫‪Mishi Kobe Niku‬‬ ‫‪97.00‬‬
‫‪18‬‬ ‫‪Carnarvon Tigers‬‬ ‫‪62.50‬‬
‫‪20‬‬ ‫‪Sir Rodney's Marmalade‬‬ ‫‪81.00‬‬
‫‪29‬‬ ‫‪Th?ringer Rostbratwurst‬‬ ‫‪123.79‬‬
‫‪38‬‬ ‫‪C?te de Blaye‬‬ ‫‪263.50‬‬
‫‪59‬‬ ‫‪Raclette Courdavault‬‬ ‫‪55.00‬‬

‫שים לב!‬

‫תת שאילתה שלא מחזירה רשומות‬


‫תת שאילתה שלא מחזירה רשומות תגרום לכך שגם השאילתה החיצונית לא תחזיר שום רשומה (אלא אם‬
‫התנאי בשאילתה החיצונית מגדיר אחרת)‪.‬‬

‫תת שאילתה המחזירה ערך ‪null‬‬


‫)‪0 row(s‬‬ ‫במידה ותת השאילתה תחזיר ערך ‪ null‬השאילתה החיצונית לא תחזיר שום רשומה‪( .‬יתקבל‬
‫)‪))affected‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪58‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫הרחבות לנושא תת השאילתא‪:‬‬

‫דוגמה לשאילתא במשפט ה‪:FROM -‬‬


‫בסיס הנתונים ‪Northwind‬‬
‫ציון מספר הפריטים בהזמנה הגדולה ביותר‪.‬‬
‫(עבור כל הזמנה מחשבים מהו סה"כ מספר הפריטים שנרכשו בה‪ ,‬ואז בודקים מי המקסימלית בין התוצאות‬
‫שהתקבלו)‬
‫)‪SELECT max(s.s_quantity‬‬
‫‪FROM ( SELECT sum(quantity) as s_quantity‬‬
‫]‪FROM [order details‬‬
‫‪GROUP BY orderId) s‬‬

‫*שים לב לשימוש בתת שאילתה במשפט ה ‪ FROM‬ובשימוש ב‪.aliases -‬‬


‫תוצאת הרצת הקוד‪:‬‬
‫‪-----------‬‬
‫‪346‬‬

‫‪EXISTS‬‬

‫אופרטור ‪ EXISTS‬בודק האם ערך מופיע ברשימת הערכים החוזרת מתת‪-‬שאילתה או לא‪.‬‬
‫אם הערך קיים‪ ,‬אופרטור ‪ EXISTS‬מחזיר ‪ TRUE‬מבלי להמשיך ולבדוק את שאר הערכים‪ ,‬ואם הערך אינו‬
‫קיים ‪ -‬מחזיר ‪( .FALSE‬אופרטור ‪ NOT EXISTS‬מבצע את הפעולה ההפוכה)‬

‫דוגמה ל‪:EXISTS -‬‬


‫בסיס הנתונים‪NorthWind:‬‬
‫הדוגמה מחזירה את ה‪ id-‬של כל הלקוחות הקיימים במאגר הלקוחות אך לא קיימת להם כרגע הזמנה במאגר‬
‫ההזמנות‪.‬‬
‫‪SELECT customerid‬‬
‫‪FROM customers‬‬
‫‪WHERE not exists(SELECT customerid‬‬
‫‪FROM orders‬‬
‫)‪WHERE customerid=customers.customerid‬‬

‫התוצאה שתתקבל מהרצת הקוד‪:‬‬


‫‪customerid‬‬
‫‪----------‬‬
‫‪FISSA‬‬
‫‪PARIS‬‬

‫עמוד ‪59‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪SET Operators - 8‬‬
‫באמצעות אופרטורי ה ‪ SET‬ניתן לבצע שילוב תוצאות ממספר שאילתות שונות יחד‪ ,‬כאשר כל אופרטור ‪SET‬‬
‫יניב שילוב אופציונאלי אחר‪.‬‬

‫מבנה השאילתה‪:‬‬

‫>‪SELECT <query 1‬‬


‫‪SET OPERATOR‬‬
‫>‪SELECT <query 2‬‬
‫ניקח לדוגמא את הטבלאות הבאות ‪:‬‬

‫טבלת עובדים‬

‫עיר‬ ‫שם משפחה‬ ‫שם פרטי‬ ‫מספר עובד‬


‫ראש העין‬ ‫מדר‬ ‫שניר‬ ‫‪1‬‬
‫תל אביב‬ ‫מסלטי‬ ‫אבי‬ ‫‪2‬‬
‫רמת גן‬ ‫נווה‬ ‫יעל‬ ‫‪3‬‬
‫רמת גן‬ ‫קדם‬ ‫רם‬ ‫‪4‬‬

‫טבלת לקוחות‬

‫עיר‬ ‫שם משפחה‬ ‫שם פרטי‬ ‫מספר לקוח‬


‫חיפה‬ ‫כהן‬ ‫משה‬ ‫‪.1‬‬
‫ירושלים‬ ‫לוי‬ ‫יוסי‬ ‫‪.2‬‬
‫תל אביב‬ ‫אברמוביץ'‬ ‫דני‬ ‫‪.3‬‬
‫חיפה‬ ‫שלום‬ ‫חגית‬ ‫‪.4‬‬

‫‪UNION‬‬

‫עובדים‬ ‫לקוחות‬

‫כאשר נשתמש ב ‪ UNION‬כשילוב בין שתי השאילתות הבאות‪ ,‬נקבל את השילוב הייחודי של‬
‫הערכים של שתיהן‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪60‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫לדוגמא‪ ,‬השאילתה הבאה ‪:‬‬
‫‪SELECT city FROM employees‬‬
‫‪UNION‬‬
‫; ‪SELECT city FROM customers‬‬

‫תניב את התוצאה ‪:‬‬

‫ראש העין‬
‫תל אביב‬
‫רמת גן‬
‫חיפה‬
‫ירושלים‬

‫‪UNION ALL‬‬

‫עובדים‬ ‫לקוחות‬

‫כאשר נשתמש ב ‪ UNION ALL‬כשילוב בין שתי השאילתות הבאות נקבל את כל התוצאות מכל השורות של‬
‫שתיהן‪.‬‬

‫לדוגמא‪ ,‬השאילתה הבאה ‪:‬‬


‫‪SELECT city FROM employees‬‬
‫‪UNION ALL‬‬
‫; ‪SELECT city FROM customers‬‬
‫תניב את התוצאה ‪:‬‬

‫ראש העין‬
‫תל אביב‬
‫רמת גן‬
‫רמת גן‬
‫חיפה‬
‫ירושלים‬
‫תל אביב‬
‫חיפה‬

‫עמוד ‪61‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪INTERSECT‬‬

‫‪INTERSECT‬‬

‫עובדים‬ ‫לקוחות‬

‫כאשר נשתמש ב ‪ INTERSECT‬כשילוב בין שתי השאילתות הבאות נקבל את כל התוצאות אשר משותפות‬
‫לשתיהן‪.‬‬

‫לדוגמא‪ ,‬השאילתה הבאה ‪:‬‬


‫‪SELECT city FROM employees‬‬
‫‪INTERSECT‬‬
‫; ‪SELECT city FROM customers‬‬
‫תניב את התוצאה ‪:‬‬

‫תל אביב‬

‫‪EXCEPT‬‬

‫לקוחות‬ ‫עובדים‬

‫כאשר נשתמש ב ‪ EXCEPT‬בין תוצאות שתי השאילתות נקבל את הערכים אשר מופיעים בשאילתה‬
‫הראשונה אך לא בשניה‬

‫לדוגמא‪ ,‬השאילתה הבאה ‪:‬‬

‫‪SELECT city FROM employees‬‬


‫‪EXCEPT‬‬
‫; ‪SELECT city FROM customers‬‬
‫תניב את התוצאה ‪:‬‬
‫ראש העין‬
‫רמת גן‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪62‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪Window Functions - 9‬‬
‫פונקציות החלון מאפשרות לבצע חישובי הקבצות מורכבים אשר אחרת היו נעשים באמצעות שפת תכנות או‬
‫פקודות ‪ SQL‬מסובכות וארוכות (כגון שימוש בתתי שאילתות מקוננות וכד')‪.‬‬
‫פונקציות חלון כמו כן מאפשרות דרך יעילה יותר להשוות בין ערכי רשומה אחת עם ערכי רשומה אחרת מאותה‬
‫הטבלה ללא צורך בשימוש ‪.Self join‬‬

‫הסינטקס הכללי ליצירת פונקצית חלון הוא‪:‬‬

‫‪Function(arg1,..., argn) OVER‬‬


‫) ]>‪( [PARTITION BY <...>] [ORDER BY <....>] [<window_clause‬‬

‫בדוגמאות הבאות נמחיש את נחיצות פונקציות החלון וכיצד ניתן להשתמש בהן בצורה בסיסית‪.‬‬

‫נתחיל בדוגמא הבאה ‪ :‬הפקודה הבאה מציגה את מס' וסכום הכולל של המוצרים לקטגוריות אולם אינה‬
‫מציגה את הנתונים בכל קבוצה‪.‬‬

‫‪SELECT COUNT(*) AS CAT_COUNT, SUM(unitprice) AS CAT_SUM‬‬


‫‪FROM products‬‬
‫)‪WHERE CategoryID IN (2, 3‬‬

‫התשובה המתקבלת היא ‪:‬‬

‫‪CAT_COUNT CAT_SUM‬‬
‫‪------------------ --------------‬‬
‫‪25‬‬ ‫‪603.83‬‬

‫כדי להציג מס' רשומות בכל קבוצת קטגוריה נאלצנו להשתמש בשורת ‪ Group by‬אשר קיבצה את הקטגוריות‬
‫לקבוצות משותפות ורק לאחר מכן התאפשר להוסיף את פונקציות הקבוצה‪.‬‬
‫החיסרון – לא ניתן לראות את פירוט הנתונים בכל קבוצה (הרי הנתונים מקובצים)‬

‫‪SELECT categoryID , COUNT(*) AS CAT_COUNT,SUM(unitprice) AS CAT_SUM‬‬


‫‪FROM Products‬‬
‫)‪WHERE CategoryID IN (2, 3‬‬
‫;‪GROUP BY CategoryID‬‬
‫תוצאת השליפה לאחר הקיבוץ‪:‬‬

‫‪CATEGORYID CAT_COUNT CAT_SUM‬‬


‫‪2‬‬ ‫‪12‬‬ ‫‪276.75‬‬
‫‪3‬‬ ‫‪13‬‬ ‫‪327.08‬‬

‫עמוד ‪63‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
OVER() -‫שימוש ב‬

OVER() -‫כעת נבצע שוב את השאילתה באמצעות פונקצית חלון ושימוש ב‬

Function(arg1,..., argn) OVER ( )

SELECT ProductID , CategoryID,


COUNT(*) OVER () CAT_COUNT, sum(unitprice) over() CAT_SUM
FROM Products
WHERE CategoryID IN (2, 3);

: ‫שימו לב לתוצאה המתקבלת בפעם זו‬


‫ הקטגוריות יחד‬2 -‫ מחזירה את סכום וכמות המוצרים הכולל ל‬CAT_SUM -‫ ו‬CAT_COUNT -‫עמודת ה‬
.‫ הרגילה‬GROUP BY ‫ דבר שלא התאפשר לפני כן ללא שימוש בפקודת ה‬.‫עם פירוט המוצרים בכל קטגוריה‬
.‫ כלל לא מופיעה ואף על פי כן אנו מציגים מידע קבוצתי יחד עם שורות רגילות‬GROUP BY ‫פקודת ה‬

productid CategoryID CAT_COUNT CAT_SUM


3 2 25 603.83
4 2 25 603.83
5 2 25 603.83
6 2 25 603.83
8 2 25 603.83
15 2 25 603.83
16 3 25 603.83
19 3 25 603.83
20 3 25 603.83
21 3 25 603.83

PARTITION -‫שימוש ב‬
:‫בדוגמא הבאה נגדיר לפונקצית הקבוצה תתי קבוצות‬

Function(arg1,..., argn) OVER ( [PARTITION BY <...>] )

SELECT ProductID , CategoryID, unitprice,


COUNT(*) OVER ( PARTITION BY categoryID ) CAT_COUNT,
SUM(unitprice) OVER(PARTITION BY categoryID ) sum_cat
FROM Products
WHERE CategoryID IN (2, 3);

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 64 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
: ‫הפעם התוצאה תראה כך‬
.‫הפעם כמות המוצרים המחושבת היא לכל קבוצת קטגוריה בנפרד‬

ProductID CategoryID unitprice CAT_COUNT CAT_SUM


3 2 10.00 12 276.75
4 2 22.00 12 276.75
5 2 21.35 12 276.75
6 2 25.00 12 276.75
66 2 17.00 12 276.75
77 2 13.00 12 276.75
16 3 17.45 13 327.08
19 3 9.20 13 327.08
20 3 81.00 13 327.08

ROWS -‫ ו‬ORDER BY -‫שימוש ב‬

.‫ מאפשרת להציג מידע מחושב מצטבר עפ"י סדר המיון‬ROWS -‫שורת ה‬

OVER ([<PARTITION BY clause>]


[<ORDER BY clause]>
[<ROWS or RANGE clause])

:‫דוגמה‬

SELECT YEAR(o.orderdate) AS "Year", unitprice,


sum(od.unitprice) OVER(PARTITION BY YEAR(orderdate) order by YEAR(orderdate)
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS
Running_sum
FROM orders o JOIN [Order Details] od
ON o.orderid = od.OrderID
WHERE CUSTOMERID = 'ALFKI'

:‫תוצאת השליפה‬

Year unitprice Running_sum

1997 45.60 45.60


1997 18.00 63.60
1997 12.00 75.60
1998 43.90 119.50
1998 10.00 129.50
1998 18.00 147.50

65 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
ROW_NUMBER

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

.‫ הינו הכרחי‬OVER -‫ בחלק ה‬order by ‫בפונקציה זאת השימוש בפקודת‬

ROW_NUMBER() OVER ([<PARTITION BY clause>]


[<ORDER BY clause]>
[<ROWS or RANGE clause])

:‫דוגמה‬

SELECT YEAR(o.orderdate) AS "YEAR" , unitprice,


row_number () OVER(PARTITION BY YEAR(orderdate) order by orderdate) AS
ROW_NUM
FROM orders o JOIN [Order Details] od
ON o.orderid = od.OrderID
WHERE CUSTOMERID = 'ALFKI'

:‫תוצאת השליפה‬

YEAR unitprice ROW_NUM

1997 45.60 1
1997 18.00 2
1997 12.00 3
1997 43.90 4
1998 55.00 1
1998 13.00 2
1998 25.00 3

OVER ([<PARTITION BY clause>]


[<ORDER BY clause]>
[<ROWS or RANGE clause])

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 66 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
RANK

.‫ מחזירה את הדירוג של ערך בתוך קבוצה‬RANK ‫הפונקציה‬

RANK() OVER ([<PARTITION BY clause>]


[<ORDER BY clause]>)

:‫בדוגמה הבאה אנו מעוניינים להציג את דירוג של מחיר המוצר ביחס לכל טבלת המוצרים עפ"י מיון בסדר יורד‬

SELECT productid, productname, unitprice,


RANK() OVER(ORDER BY unitprice DESC) AS pricerank
FROM Products
ORDER BY pricerank;

:‫תוצאת השליפה תהיה‬


productid productname unitprice pricerank

62 Tarte au sucre 49.30 1


43 Ipoh Coffee 46.00 2
28 R?ssle Sauerkraut 45.60 3
27 Schoggi Schokolade 43.90 4
63 Vegie-spread 43.90 4
8 Northwoods Cranberry Sauce 40.00 6
17 Alice Mutton 39.00 7
12 Queso Manchego La Pastora 38.00 8
56 Gnocchi di nonna Alice 38.00 8
69 Gudbrandsdalsost 36.00 10

ֹDENSE_RANK
‫ הדירוגים שלה‬RANK-‫ אך בניגוד ל‬,RANK ‫ עובדת בדיוק כמו הפונקציה‬DENSE_RANK ‫הפונקציה‬
.‫עוקבים‬

DENSE_RANK () OVER(ORDER BY unitprice DESC) AS pricerank

productid productname unitprice pricerank

62 Tarte au sucre 49.30 1


43 Ipoh Coffee 46.00 2
28 R?ssle Sauerkraut 45.60 3
27 Schoggi Schokolade 43.90 4
63 Vegie-spread 43.90 4
8 Northwoods Cranberry Sauce 40.00 5
17 Alice Mutton 39.00 6
12 Queso Manchego La Pastora 38.00 7
56 Gnocchi di nonna Alice 38.00 7
69 Gudbrandsdalsost 36.00 8

67 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
NTILE

.‫ עם חריגה של איבר אחד לכל היותר‬,‫ מחלקת את המידע לקבוצות שוות בגדלם‬NTILE ‫הפונקציה‬

SELECT productid, productname, unitprice,


NTILE (4) OVER(ORDER BY unitprice DESC) AS pricerank
FROM Products
where unitprice <10
ORDER BY pricerank;

productid productname unitprice pricerank

62 Tarte au sucre 49.30 1


43 Ipoh Coffee 46.00 1
28 R?ssle Sauerkraut 45.60 1
27 Schoggi Schokolade 43.90 2
63 Vegie-spread 43.90 2
8 Northwoods Cranberry Sauce 40.00 2
17 Alice Mutton 39.00 3
12 Queso Manchego La Pastora 38.00 3
56 Gnocchi di nonna Alice 38.00 4
69 Gudbrandsdalsost 36.00 4

Window Offset Functions

Lag / Lead Functions

‫ באמצעותן ניתן לקבל גישה בשורה הנוכחית לשדות אשר‬,‫פונקציות אלה נחשבות לחלק מפונקציות החלון‬
.‫קיימות בשורות הבאות והקודמות‬
‫נדגים את פונקציות אלה באמצעות השאילתה הבאה‬

SELECT productID , ProductName , UnitPrice


FROM products
ORDER BY productID

‫נניח כי התוצאה המתקבלת תהיה‬

ProductID ProductName UnitPrice


------------- ----------------- -------------
1 Bisli 10
2 Bamba 20
3 Milk 30
4 Salt 50
5 Coffee 20

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 68 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫כעת נרצה לבצע שליפה אשר תציג עבור כל מוצר את מחיר המוצר שאחריו ואת מחיר המוצר שלפניו‪.‬‬
‫כדי לבצע זאת נשתמש בסינטקס הבא ‪:‬‬

‫‪SELECT productID,‬‬
‫‪ProductName ,‬‬
‫‪unitPrice ,‬‬
‫‪LAG(unitPrice, 1) OVER (ORDER BY unitPrice) as lag,‬‬
‫‪LEAD(unitPrice,1) OVER (ORDER BY unitPrice) as lead‬‬
‫‪FROM products‬‬
‫‪WHERE categoryID = 1‬‬
‫;‪ORDER BY unitPrice‬‬

‫התוצאה אשר תתקבל תהיה ‪:‬‬

‫‪ProductID ProductName UnitPrice‬‬ ‫‪lag‬‬ ‫‪lead‬‬


‫‪------------ ---------------- ----------‬‬ ‫‪-----‬‬ ‫‪-----‬‬
‫‪1‬‬ ‫‪Bisli‬‬ ‫‪10‬‬ ‫‪NULL‬‬ ‫‪20‬‬
‫‪2‬‬ ‫‪Bamba 20‬‬ ‫‪10‬‬ ‫‪30‬‬
‫‪3‬‬ ‫‪Milk‬‬ ‫‪30‬‬ ‫‪20‬‬ ‫‪50‬‬
‫‪4‬‬ ‫‪Salt‬‬ ‫‪50‬‬ ‫‪30‬‬ ‫‪20‬‬
‫‪5‬‬ ‫‪Coffee‬‬ ‫‪20‬‬ ‫‪50‬‬ ‫‪NULL‬‬

‫בפונקצית ‪ Lag‬אשר מתייחסת לערכים הקודמים אנו מגדירים את הפרמטרים הבאים ‪:‬‬

‫)מספר ‪ -‬המציין כמה שורות אחורה ‪,‬שם עמודה(‪LAG‬‬


‫כינוי ‪) as‬עמודה על פיה יתבצע המיון ‪OVER (ORDER BY‬‬

‫בפונקצית ‪ Lead‬אשר מתייחסת לערכים הבאים אנו מגדירים את הפרמטרים הבאים ‪:‬‬

‫)מספר ‪ -‬המציין כמה שורות קדימה ‪,‬שם עמודה(‪LEAD‬‬


‫כינוי ‪) as‬עמודה על פיה יתבצע המיון ‪OVER (ORDER BY‬‬

‫לסיכום‪:‬‬

‫פונקציות חלון מאפשרות להסתכל על רשומה בודדת כחלק מקבוצה לוגית של נתונים‬ ‫•‬

‫מאפשרות לחלק את המידע לקבוצות (‪)PARTITIONS‬‬ ‫•‬

‫לדרג רשומות ע"פ סדר מוגדר (‪)ORDER‬‬ ‫•‬

‫עמוד ‪69‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
Common Table Expressions (CTE) -10 ‫פרק‬
‫ וכד' יכולה‬Group Functions ,Sub Queries ,Join ‫לעיתים קריאת שאילתות ארוכות המורכבות מפעולות‬
.‫להיות מאוד מורכבת‬
‫ יש בידינו את היכולת לפשט את רמת מורכבות הקריאה של אותן שאילתות ולהופכן לברורות‬CTE ‫באמצעות ה‬
.‫וקלות יותר לתחזוקה‬

:‫המבנה הכללי של הפונקציה‬


WITH <CTE name>
AS
(<CTE_definition>)
<Outer Query referencing CTE>;
: ‫ניקח לדוגמא את השאילתה הבאה‬

SELECT p.ProductName,
c.CategoryName,
p.UnitPrice
FROM Products p JOIN Categories c ON
c.CategoryID = p.CategoryID
WHERE p.UnitPrice > 10.0

: ‫ אנו נשכתב את שאילתה זו לקוד הבא‬CTE ‫באמצעות ה‬

WITH products_and_categories (ProductName, CategoryName, UnitPrice)


AS
( SELECT
p.ProductName,
c.CategoryName,
p.UnitPrice
FROM Products p JOIN Categories c ON
c.CategoryID = p.CategoryID
WHERE p.UnitPrice > 10.0)
SELECT ProductName, CategoryName, UnitPrice
FROM products_and_categories

‫ גורמים‬3 ‫ ל‬CTE ‫ננתח את השאילה האחרונה שנבנתה באמצעות ה‬

‫ הגדרת הכינויים‬- WITH ‫ פקודת ה‬.‫א‬

WITH products_and_categories (ProductName, CategoryName, UnitPrice)

‫ אנו נותנים לכל אחד‬,‫בחלק זה אנו מגדירים את התכנים (עמודות וטבלאות) אשר ישמשו אותנו בחלק הבא‬
.‫מתכנים אלו כינויים לפי הבחירה שלנו‬

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 70 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫ב‪ .‬פקודת ה ‪ - AS‬בניית שאילתת המקור‬

‫‪AS‬‬
‫(‬
‫‪SELECT‬‬
‫‪p.ProductName,‬‬
‫‪c.CategoryName,‬‬
‫‪p.UnitPrice‬‬
‫‪FROM Products p JOIN Categories c ON‬‬
‫‪c.CategoryID = p.CategoryID‬‬
‫‪WHERE p.UnitPrice > 10.0‬‬
‫)‬

‫בחלק זה אנו בונים את השאילתה עצמה‪ ,‬שימו לב כי סדר הכינויים אשר הוגדרו בשלב א' חייב לתאום לסדר‬
‫העמודות בחלק ב' ‪ -‬שאילתת המקור‪.‬‬

‫ג‪ .‬יצירת השאילתה המופשטת‪.‬‬

‫‪SELECT ProductName, CategoryName, UnitPrice‬‬


‫‪FROM products_and_categories‬‬

‫באמצעות שלב זה אנו משלבים את חלק א' (יצירת הכינויים) וחלק ב' (שאילתת המקור) יחד ויוצרים שאילתה‬
‫אשר תהיה יותר ברורה ופשוטה לתחזוק‪.‬‬

‫דוגמה נוספת ליצירת שאילתת ‪ CTE‬והפעם מתן כינויים לעמודות בחלק של שאילתת המקור < ‪CTE‬‬
‫‪:>definition‬‬

‫‪WITH CTE_year‬‬
‫‪AS‬‬
‫‪(SELECT YEAR(orderdate) AS orderyear, customerid‬‬
‫) ‪FROM orders‬‬
‫‪SELECT orderyear, count(DISTINCT customerid) AS cust_count‬‬
‫‪FROM CTE_year‬‬
‫;‪GROUP BY orderyear‬‬

‫עמוד ‪71‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
Pivoting - 11 ‫פרק‬

PIVOT

‫ ניתן להפוך מידע טבלאי רגיל המגיע כתוצאה משאילתות מסויימות למידע המופיע‬Pivot ‫באמצעות פקודת ה‬
.‫כטבלת ציר‬

: ‫נשתמש בטבלת המכירות הבאה‬


SELECT * FROM sales ;

Year Quarter Month Amount


2012 Q1 January 1000
2012 Q1 February 2000
2012 Q1 March 3000
2012 Q2 April 4000
2012 Q2 May 5000
2012 Q2 June 6000
2012 Q3 July 7000
2012 Q3 August 8000
2012 Q3 September 9000
2012 Q4 October 10000
2012 Q4 November 11000
2012 Q4 December 12000

: ‫ השאילתה הבאה‬,‫עבור טבלה זו‬

SELECT year , quarter , AVG(amount) AS AVG_AMOUNT


FROM sales
GROUP BY year , quarter

: ‫תניב את התוצאה הבאה‬

Year Quarter AVG_AMOUNT


2012 Q1 2000
2012 Q2 5000
2012 Q3 8000
2012 Q4 11000

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 72 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫כעת נרצה להציג את התוצאה לפי מבנה טבלת ציר כאשר השנה תהיה ציר ה ‪ X‬והרבעון יהיה ציר ה ‪Y‬‬

‫‪Year‬‬ ‫‪Q1‬‬ ‫‪Q2‬‬ ‫‪Q3‬‬ ‫‪Q4‬‬


‫‪2012‬‬ ‫‪2000‬‬ ‫‪5000‬‬ ‫‪8000‬‬ ‫‪11000‬‬

‫כדי להציג את התוצאות בצורה זו נשתמש בפקודת ה ‪PIVOT‬‬

‫]‪SELECT s_year , [Q1] , [Q2] , [Q3] , [Q4‬‬


‫‪FROM‬‬
‫‪(SELECT s_year , s_quarter , AVG(amount) AS AVG_AMOUNT‬‬
‫‪FROM sales‬‬
‫‪GROUP BY s_year , s_quarter) source_tab‬‬
‫‪PIVOT (SUM(AVG_AMOUNT) FOR s_quarter IN ([Q1] , [Q2] , [Q3] , [Q4])) AS pvt‬‬

‫פקודת ה ‪ PIVOT‬נחלקת ל ‪ 3‬חלקים‬

‫‪ .1‬חלק ראשון ‪ -‬מגדיר את התצוגה הרצויה כאשר העמודה הראשונה מייצגת את ציר ה ‪ Y‬ושאר העמודות‬
‫מייצגות את ציר ה ‪X‬‬

‫]‪SELECT s_year , [Q1] , [Q2] , [Q3] , [Q4‬‬

‫‪ .2‬חלק שני ‪ -‬מ גדיר את את השאילתה אותה אנו רוצים להמיר לטבלת ציר (ממנה אנו למעשה שואבים‬
‫את הנתונים)‬

‫‪(SELECT s_year , s_quarter , AVG(amount) AS AVG_AMOUNT‬‬


‫‪FROM sales‬‬
‫‪GROUP BY s_year , s_quarter) source_tab‬‬

‫‪ .3‬חלק שלישי ‪ -‬פקודת ה ‪ ,PIVOT‬בחלק זה אנו מגדירים ‪:‬‬


‫כיצד יש להציג את המידע (במקרה הספציפי לפקודת ה ‪ SUM‬אין משמעות כי מלכתחילה לכל רבעון יש רק‬
‫שורה אחת)‬
‫ועבור אילו ערכים (רבעונים במקרה שלנו)‬

‫‪PIVOT (SUM(AVG_AMOUNT) FOR s_quarter IN ([Q1] , [Q2] , [Q3] , [Q4])) AS pvt‬‬

‫עמוד ‪73‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪UNPIVOT‬‬

‫האופרטור ‪ UNPIVOT‬נותן לנו להמיר עמודות בטבלה לרשומות‬

‫לשם כך ניצור את הטבלה הבאה המתארת את כמות הזמנות שביצע כל עובד בכל שנה‪ .‬המידע של השנים‬
‫מוצג כעמודות‪.‬‬

‫‪CREATE TABLE unpivottable‬‬


‫‪(employeeid INT,‬‬
‫‪[1996] INT,‬‬
‫‪[1997] INT,‬‬
‫;)‪[1998] INT‬‬

‫נוסיף את הנתונים הבאים‪:‬‬

‫‪INSERT INTO unpivottable‬‬


‫‪VALUES (1,18,25,30),‬‬
‫‪(2,45,68,34),‬‬
‫‪(3,48,76,52),‬‬
‫)‪(4,62,12,47‬‬
‫המידע מוצג כך‪:‬‬
‫‪employeeid‬‬ ‫‪1996‬‬ ‫‪1997‬‬ ‫‪1998‬‬
‫‪1‬‬ ‫‪18‬‬ ‫‪25‬‬ ‫‪30‬‬
‫‪2‬‬ ‫‪45‬‬ ‫‪68‬‬ ‫‪34‬‬
‫‪3‬‬ ‫‪48‬‬ ‫‪76‬‬ ‫‪52‬‬
‫‪4‬‬ ‫‪62‬‬ ‫‪12‬‬ ‫‪47‬‬

‫וכעת נמיר את הנתונים שבעמודת השנים למידע של רשומות באמצעות ‪.Unpivot‬‬

‫‪SELECT employeeid, year , countorders‬‬


‫‪FROM (SELECT employeeid, [1996],[1997],[1998] FROM unpivottable ) p‬‬
‫;‪UNPIVOT (countorders FOR year IN ([1996],[1997],[1998])) AS unpvt‬‬

‫המידע לאחר ‪ Unpivot‬יוצג כך‪:‬‬


‫‪employeeid‬‬ ‫‪year‬‬ ‫‪countorders‬‬
‫‪1‬‬ ‫‪1996‬‬ ‫‪18‬‬
‫‪1‬‬ ‫‪1997‬‬ ‫‪25‬‬
‫‪1‬‬ ‫‪1998‬‬ ‫‪30‬‬
‫‪2‬‬ ‫‪1996‬‬ ‫‪45‬‬
‫‪2‬‬ ‫‪1997‬‬ ‫‪68‬‬
‫‪2‬‬ ‫‪1998‬‬ ‫‪34‬‬
‫‪3‬‬ ‫‪1996‬‬ ‫‪48‬‬
‫‪3‬‬ ‫‪1997‬‬ ‫‪76‬‬
‫‪3‬‬ ‫‪1998‬‬ ‫‪52‬‬
‫‪4‬‬ ‫‪1996‬‬ ‫‪62‬‬
‫‪4‬‬ ‫‪1997‬‬ ‫‪12‬‬
‫‪4‬‬ ‫‪1998‬‬ ‫‪47‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪74‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪ – 12‬פקודות ‪Data Manipulation Language – DML‬‬
‫פקודות ‪ Data manipulation language - DML‬הינן אחראיות על שינויים ברשומות בסיס הנתונים‪.‬‬
‫קיימות ‪ 3‬פקודות בסיסיות והן‪:‬‬
‫‪ - Insert‬הוספת רשומה‪.‬‬
‫‪ - Update‬עדכון רשומה‪.‬‬
‫‪ -Delete‬מחיקת רשומה‪.‬‬

‫הוספת רשומה – ‪INSERT‬‬

‫פקודה זו מוסיפה שורה חדשה לבסיס הנתונים‪ .‬הפקודה מכילה את שם הטבלה אליה יש להוסיף את השורה‬
‫החדשה ואת הערכים שעל השורה החדשה להכיל‪.‬‬

‫מבנה הפקודה‪:‬‬
‫שם טבלה ‪INSERT INTO‬‬
‫)רשימת ערכים מופרדת ע"י פסיקים( ‪VALUES‬‬
‫*הערכים חייבים להופיע לפי סדר הגדרתם בטבלה‪.‬‬

‫דוגמה‪:‬‬

‫בסיס נתונים‪.Northwind:‬‬
‫הוספת רשומה לטבלת ‪.Order Details‬‬

‫]‪INSERT INTO [Order Details‬‬


‫)‪VALUES (10248, 12, 23.2, 4, 0.15‬‬

‫דרך נוספת המאפשרת לא להכניס את כל נתוני הטבלה ‪ ,‬או לא לפי סדר הופעתם הינה ע"י ציון שמות העמודות‬
‫ע"פ המבנה הבא‪:‬‬

‫)שמות העמודות אליהן יוזנו הערכים( שם טבלה ‪INSERT INTO‬‬


‫)רשימת ערכים מופרדת ע"י פסיקים( ‪Values‬‬

‫דוגמה‪:‬‬

‫בסיס נתונים‪.Northwind:‬‬
‫הוספת רשומה לטבלת ‪.Order Details‬‬

‫]‪INSERT INTO [Order Details‬‬


‫)‪(Discount, Quantity, UnitPrice,ProductID,OrderID‬‬
‫) ‪VALUES (0.15, 4, 23.2, 12, 10248‬‬

‫עמוד ‪75‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫הוספת רשומות מטבלה אחרת‬

‫ניתן לבצע הוספה של רשומות מטבלה אחת לטבלה שניה על ידי שימוש בשאילתא השולפת עמודות ורשומות‬
‫מסויימות (או את כולן) מהטבלה ממנה נרצה להעתיק את הרושמות‪ .‬נבצע זאת ע"פ המבנה הבא‪:‬‬

‫שם טבלה ‪INSERT INTO‬‬


‫‪Select query‬‬

‫דוגמה‪:‬‬
‫‪INSERT INTO A‬‬
‫‪SELECT * from B‬‬
‫…‪WHERE‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫הכנסת כל ההזמנות שבוצעו בשנת ‪ 1996‬לטבלה חדשה בשם ‪.orders_96‬‬
‫(שים לב שהטבלה לא קיימת כרגע בבסיס הנתונים‪ ,‬ועל כן על מנת להריץ את השאילתה יש ליצור אותה)‪.‬‬

‫( ‪INSERT INTO orders_96 (order_id,customerid‬‬


‫‪SELECT orderid,customerid‬‬
‫‪FROM orders‬‬
‫'‪WHERE OrderDate LIKE '%1996%‬‬

‫הכנסת ערכי ‪ Null‬ו ‪Default -‬‬

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

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫דוגמה זו מוסיפה שורה חדשה לטבלת ‪.order details‬‬
‫ומגדירה ‪ OrderID‬מספר‪ 10248:‬ו‪ ProductID-‬מספר ‪.12‬‬
‫העמודות ‪ UnitPrice, Quantity, Discount‬מאפשרות ערכי ‪ NULL‬או ברירת מחדל ולכן לא מקבלות ערך‬
‫ספציפי‪.‬‬

‫]‪INSERT [Order Details‬‬


‫) ‪VALUES (10248, 12, DEFAULT,DEFAULT, NULL‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪76‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרמטר )‪@@IDENTITY (T-SQL‬‬
‫קיימת אפשרות שהמערכת תי תן מספור אוטומטי לעמודות מסויימות (בעיקר עמודות מפתח) על ידי הגדרת‬
‫העמודה עם ‪.IDENTITY‬‬

‫כאשר מבצעים שאילתה הפונה לטבלה המכילה מספור אוטומטי הערך אשר ניתן ע"י המערכת עבור הרשומה‬
‫שצורפה נשמר בתוך משתנה גלובלי ששמו ‪ @@IDENTITY‬המאותחל כל ‪( SESSION‬חיבור ל ‪ )DB‬ולכן‬
‫לאחר הרצת משפט ‪ INSERT‬לטבלה המכילה מספור אוטומטי (עמודת ‪ ,)Identity‬ניתן לפנות למשתנה‬
‫ולראות את הערך שבתוכו‪.‬‬

‫משום שהערך עבור עמודה זו מחולל בצורה אוטומטית‪ ,‬לא ניתן להזין את הערך ידנית‪.‬‬

‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫דוגמה זו מוסיפה מוביל חדש בשם ‪ Kangaroo‬לטבלת ‪.Shippers‬‬
‫העדכון מתבצע ללא שימוש ברשימת עמודות‪.‬‬
‫שים לב כי העמודה ‪ ShipperID‬היא בעלת התכונה ‪( IDENTITY‬מספור אוטומטי) ועל כן אינה מופיעה‬
‫ברשימת העמודות וזאת כיוון שהמערכת מזינה ערך לעמודה זו באופן עצמאי‪ .‬העמודה ‪ Phone‬מאפשרת‬
‫ערכי ‪ NULL‬ולכן השתמשנו בערך זה‪.‬‬

‫‪INSERT‬‬ ‫‪INTO‬‬ ‫‪Shippers‬‬


‫)‪VALUES (‘Kangaroo’, NULL‬‬

‫קבלת הרשומה החדשה ע"פ המספר שקיבל ערך ה‪:IDENTITY-‬‬

‫‪SELECT * FROM Shippers‬‬


‫‪WHERE ShipperID = @@IDENTITY‬‬

‫כתוצאה מהרצת הקוד נקבל‪:‬‬

‫‪ShipperID‬‬ ‫‪CompanyName‬‬ ‫‪Phone‬‬


‫‪------------------------ ---------------------------------------- -‬‬
‫‪Kangaroo‬‬ ‫‪NULL‬‬ ‫‪5‬‬

‫(‪)row(s) affected 1‬‬

‫*אם משפט ה‪ INSERT-‬לא השפיע על אף אחת מהטבלאות עם עמודה המוגדרת‬


‫כ‪ @@IDENTITY, identity -‬מחזיר את הערך ‪.NULL‬‬

‫עמוד ‪77‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫עדכון רשומה ‪Update -‬‬

‫הפקודה ‪ update‬מאפשרת עדכון של ערכים ברשומה בודדת או עדכון בו‪-‬זמני של מספר רשומות המקיימות‬
‫תנאי לוגי כלשהו‪.‬‬

‫מבנה הפקודה ‪:‬‬


‫שם טבלה ‪UPDATE‬‬
‫]ערך חדש = שם עמודה‪ [,‬ערך חדש = שם עמודה ‪SET‬‬
‫[תנאי ‪]WHERE‬‬

‫ניתן לעדכן בו זמנית מספר עמודות ע"י פסיק וצרוף צמדים נוספים של שם העמודה ‪ +‬ערך תחת אותו משפט‬
‫‪.SET‬‬
‫נהוג לצרף תנאי במשפט ‪ WHERE‬שכן אחרת כל הרשומות בטבלה מעודכנות‪.‬‬

‫דוגמה‪:‬‬
‫בסיס הנתונים‪Northwind :‬‬
‫הדוגמה הבאה מכפילה את ערך העמודה ‪ UnitPrice‬של כל השורות בטבלה ‪.Order Details‬‬

‫]‪UPDATE [Order Details‬‬


‫‪SET UnitPrice = UnitPrice * 2‬‬

‫דוגמה לשימוש בתת שאילתה בעת עדכון ועדכון מספר עמודות‪:‬‬


‫בסיס הנתונים‪Northwind :‬‬
‫הדוגמה הבאה מעדכנת את טבלת ‪.Order Details‬‬
‫הרשומות המעודכנות הן של מוצרים אשר מחירם קטן מ‪ 12 -‬כאשר העדכונים הם‪:‬‬
‫‪ ‬מחיר יחידת כל מוצר כעת הוא הערך המקסימלי של ‪ UnitPrice‬הנמצא בטבלת ‪.Product‬‬
‫‪ ‬הכמות בהזמנה היא הערך הממוצע של כמות המוצרים שנמצאת בטבלת ‪.Order Details‬‬

‫]‪UPDATE [Order Details‬‬


‫‪SET UnitPrice = (SELECT MAX(UnitPrice) FROM Products),‬‬ ‫‪Quantity = (SELECT‬‬
‫)]‪AVG(Quantity) FROM [Order Details‬‬ ‫‪WHERE UnitPrice < 12‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪78‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫מחיקת רשומה ‪Delete -‬‬

‫הפקודה ‪ delete‬מוחקת רשומות מבסיס הנתונים‪.‬‬

‫מבנה הפקודה‪:‬‬
‫שם טבלה ]‪DELETE [FROM‬‬

‫נהוג לצרף תנאי במשפט ‪ where‬שכן אחרת כל הרשומות בטבלה נמחקות‪.‬‬


‫לכן‪:‬‬
‫שם טבלה ]‪DELETE [FROM‬‬
‫תנאי ‪WHERE‬‬

‫דוגמה‪:‬‬
‫בסיס הנתונים‪Northwind :‬‬
‫הדוגמה הבאה מוחקת את כל הרשומות מטבלת [‪.]Order Details‬‬
‫]‪DELETE FROM [Order Details‬‬

‫דוגמה‪:‬‬
‫בסיס הנתונים‪Northwind :‬‬
‫הדוגמה הבאה מוחקת את הרשומות מטבלת [‪ ]Order Details‬אשר שדה ה‪ Quantity -‬שלהם קטן מ ‪.5 -‬‬

‫]‪DELETE FROM [Order Details‬‬


‫‪WHERE Quantity < 5‬‬

‫דוגמה למחיקה על ידי שימוש בתת שאילתה‪:‬‬


‫בסיס הנתונים‪Northwind :‬‬
‫הדוגמה הבאה מוחקת את הרשומות מטבלת [‪ ]Order Details‬אשר ה‪ UnitPrice -‬שלהם גדול מ ‪30 -‬‬
‫ותאריך ביצוע ההזמנה גדול משנתיים‪.‬‬

‫]‪DELETE FROM [Order Details‬‬


‫‪WHERE OrderID IN‬‬
‫‪(SELECT OrderID‬‬
‫‪FROM Orders‬‬
‫)‪WHERE DATEDIFF(YEAR,OrderDate,GETDATE()) > 2‬‬
‫‪AND UnitPrice > 30‬‬

‫ביצוע ‪ Truncate‬לטבלה‬
‫פעולת ‪ Truncate‬הינה פעולה המנקה את הטבלה מתוכנה ומחזירה אותה למצב ההתחלתי לפני הזנת נתונים‬
‫כלשהם בתוכה (מספורים אוטומטים מתאפסים)‪.‬‬
‫הפעולה משחררת את הזיכרון שהוקצה עבור הנתונים‪.‬‬
‫היא מהירה יותר מפקודת ‪ delete‬ולא ניתן להפעילה על חלק מהרשומות אלא תמיד על כולן יחד‪.‬‬

‫מבנה הפקודה‪:‬‬
‫שם טבלה ‪Truncate table‬‬
‫דוגמה‪:‬‬
‫‪Truncate table authors‬‬

‫עמוד ‪79‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫טרנזקציות ופקודות ‪DML‬‬

‫טרנזקציה היא יחידה לוגית הכוללת פקודת ‪ DML‬אחת או יותר ונסגרת בהצלחה או בכשלון‪.‬‬
‫ב ‪ SQL SERVER‬כברירת מחדל‪ ,‬כל פקודת ‪ DML‬היא טרנזקציה בפני עצמה – כלומר הטרנזקציה נפתחת‬
‫באופן אוטומטי ונסגרת בסיום אותה פקודה‪.‬‬

‫ניתן לפתוח טרנזקציה בצורה מפורשת על ידי ‪ BEGIN TRANSACTION‬ולסגור טרנזקציה בכשלון על ידי‬
‫‪ ROLLBACK‬או בהצלחה על ידי ‪.COMMIT‬‬

‫מה הכוונה לסיום טרנזקציה בהצלחה?‬


‫כל פקודות ה ‪ DML‬אשר תחת אותה הטרנזקציה ייבוצעו בפועל – כלומר השינויים אשר בוצעו על ידי פקודות‬
‫אלו יישמרו באופן תמידי וסופי‪.‬‬

‫מה הכוונה לסיום טרנזקציה בכשלון?‬


‫כל פקודות ה ‪ DML‬אשר תחת אותה הטרנזקציה שנפתחה ייכשלו – כלומר ייתבצע ‪ ROLLBACK‬לכל‬
‫הפקודות (‪.)UNDO‬‬

‫לדוגמא‪:‬‬

‫‪UPDATE‬‬ ‫נפתחה ונסגרה טרנזקציה‪‬‬

‫‪BEGIN TRAN‬‬ ‫נפתחה טרנזקציה ‪‬‬


‫‪INSERT‬‬
‫‪DELETE‬‬
‫‪INSERT‬‬
‫‪SELECT‬‬
‫‪INSERT‬‬
‫‪ROLLBACK‬‬ ‫נסגרה טרנזקציה בכשלון ‪‬‬

‫‪BEGIN TRAN‬‬ ‫נפתחה טרנזקציה ‪‬‬


‫‪UPDATE‬‬
‫‪INSERT‬‬
‫‪COMMIT‬‬ ‫נסגרה טרנזקציה בהצלחה ‪‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪80‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪ - 13‬פקודות ‪Data Definition Language – DDL‬‬
‫פקודות ‪ DDL‬הינן פקודות המתבצעות על אובייקטים בבסיס הנתונים‪ .‬נשתמש בפקודות אלו ליצירת‬
‫אובייקטים ב ‪ ,DATA BASE‬עדכון הגדרות לאובייקטים קיימים ומחיקה של אובייקטים‪.‬‬

‫אובייקטים הם מבנים במערכת בעלי תכונות משותפות אשר נשמרים ב ‪ DATA BASE‬תחת שם ייחודי‬
‫המורכב מ – שם_אובייקט‪.‬שם_סכמה‪.‬שם_‪. DB‬‬

‫סכמה היא ‪ namespace‬ב‪ data base‬אשר מכיל אובייקטים בעלי הקשר ביניהם (קשר מקצועי כלשהו‪.‬‬
‫לדוגמא‪ ,‬כל האובייקטים תחת נושא מכירות ישוייכו לסכמה שתקרא ‪ ,SALES‬כל האובייקטים תחת נושא כוח‬
‫אדם ישוייכו לסכמה שתקרא‬
‫‪ HUMAN RESOURCE‬וכו'‪)...‬‬
‫סכמת ברירת המחדל ב ‪ SQL SERVER‬נקראת ‪ ,DBO‬יצירת כל אובייקט ללא ציון שם הסכמה ישוייך בצורה‬
‫אוטומטית לסכמת ה ‪.DBO‬‬
‫ניתן להגדיר עבור כל משתמש מהי סכמת ברירת המחדל שלו‪ ,‬כך שבגישה לכל אובייקט (ללא ציון שם‬
‫האובייקט המלא) באותו היוזר תתבצע קודם לאותה סכמה ברירת המחדל אליו המשתמש שייך ובמידה‬
‫והאובייקט לא יימצא באותה הסכמה‪ ,‬יבוצע חיפוש בצורה אוטומטית בסכמת ה ‪.DBO‬‬

‫‪CREATE TABLE‬‬
‫פקודות ‪ DDL‬לאובייקט מסוג טבלה‪:‬‬

‫יצירת טבלה‬
‫שם טבלה ‪Create table‬‬
‫(‬
‫]‪Column_name data_type [DEFAULT] [IDENTITY] [CONSTRAINT‬‬
‫]‪[,column_name….‬‬
‫)‬

‫דוגמה ליצירת טבלה בסיסית לפרטי הזמנה‪:‬‬

‫]‪CREATE TABLE [Order Details‬‬


‫(‬
‫‪OrderID INT ,‬‬
‫‪ProductID INT ,‬‬
‫‪UnitPrice MONEY,‬‬
‫‪Quantity SMALLINT (1),‬‬
‫‪Discount REAL‬‬
‫)‬

‫בדוגמה זו הגדרנו טבלה המכילה ‪ 5‬עמודות כאשר המגבלה היחידה אשר חלה עליהן היא סוג הנתונים אשר‬
‫יוזנו באותה העמודה‪ .‬ניתן להגדיר מגבלות (או אילוצים) נוספים על אותן העמודות‪ ,‬על כך נדון בהמשך‪.‬‬

‫עמוד ‪81‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫לדוגמה‪ :‬בשדה ‪ Discount‬ניתן להזין כל מספר ממשי‪ ,‬מה שכולל גם מספר שלילי‪ ,‬לא קיימים שום ערכי‬
‫ברירת מחדל‪ ,‬אילוץ או קשר כלשהו לאותה העמודה‪.‬‬

‫* ניתן ליצור טבלה מבוססת על נתוני טבלה אחרת על ידי המבנה הפקודה הבא‪:‬‬

‫‪SELECT */column_name‬‬
‫‪INTO new_table_name‬‬
‫‪FROM table_name‬‬
‫]‪[WHERE condition‬‬

‫הוספת ערך ברירת מחדל לעמודה‬


‫ניתן לקבוע עבור עמודה ערך ברירת מחדל ‪ ,‬ערך ברירת המחדל יכול להיות‪:‬‬
‫‪ ‬ערך קבוע‬
‫‪ ‬פונקציה‬
‫‪ ‬ביטוי מתמטי‬

‫מבנה‪:‬‬
‫‪Column_name data_type‬‬ ‫)ערך ברירת המחדל ( ‪default‬‬

‫דוגמה למבנה הכתיבה‪:‬‬


‫)‪…..Quantity SMALLINT DEFAULT (1‬‬

‫*שימו לב כמובן כי הערך שהוכנס כברירת מחדל מתאים ל‪ datatype -‬שהוגדר עבור העמודה‪.‬‬
‫הגדרת שדה מספור אוטומטי‪Identity -‬‬
‫שדה מספור אוטומטי הינו שדה אשר המערכת יוצרת עבורו מספרים ברצף כאשר מופע כל מספר הוא חד‬
‫ערכי‪.‬‬
‫שדה אוטומטי נקרא ‪ Identity‬והוא מקבל שני פרמטרים‪:‬‬
‫‪ -Seed‬הערך ההתחלתי של המספור‬
‫‪ -Increment‬הערך שיוסף בכל פעם למספר האחרון שנוצר‪.‬‬

‫מבנה המספור‪:‬‬
‫( ‪IDENTITY ( seed , increment‬‬

‫שיוך המספור לשדה המוגדר ביצירת טבלה‪:‬‬


‫)‪….Id_num int identity(1,1‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪82‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪ALTER TABLE‬‬
‫שינויים במבנה הטבלה‬
‫שינויים במבנה הטבלה מתבצעים ע"י שימוש בפקודה ‪.Alter‬‬

‫דוגמאות‪:‬‬
‫הוספת עמודה לטבלה‪:‬‬
‫)‪ALTER TABLE customers ADD phone nvarchar(10‬‬

‫מחיקת עמודה מטבלה‪:‬‬


‫‪ALTER TABLE customers DROP COLUMN phone‬‬

‫‪DROP TABLE‬‬
‫מחיקת טבלה ‪-‬‬
‫שם טבלה ‪Drop table‬‬

‫*שים לב שלא מדובר במחיקת הרשומות בטבלה אלא במחיקת כל הטבלה כולל הגדרת המבנה שלה‪.‬‬

‫עמוד ‪83‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫הוספת אילוצים לטבלה ‪Constraints -‬‬

‫כפי שכבר ציינו‪ ,‬על מנת שבסיס הנתונים יהיה יציב ויכיל מידע חוקי יש בין השאר להכיל חוקים על עמודות‬
‫אשר יכפו על המערכת לקיימם‪.‬‬
‫‪ - Constraints‬קבוצת החוקים אשר ניתן להכיל על העמודות השונות והם‪:‬‬

‫(שם קיצור – ‪)NN‬‬ ‫‪Not Null‬‬ ‫‪‬‬


‫(שם קיצור – ‪)CK‬‬ ‫‪Check‬‬ ‫‪‬‬
‫(שם קיצור – ‪)UK‬‬ ‫‪Unique‬‬ ‫‪‬‬
‫(שם קיצור – ‪)PK‬‬ ‫‪Primary Key‬‬ ‫‪‬‬
‫(שם קיצור – ‪)FK‬‬ ‫‪Foreign Key‬‬ ‫‪‬‬

‫את האילוצים ניתן להגדיר בשתי רמות‪:‬‬


‫האילוץ‪.‬‬ ‫הגדרת‬ ‫את‬ ‫מוסיפים‬ ‫העמודה‬ ‫הגדרת‬ ‫בעת‬ ‫–‬ ‫עמודה‬ ‫‪ ‬רמת‬
‫מבנה‪:‬‬

‫‪Column_definition [CONSTRAINT constraint_nick_name] constraint_type‬‬

‫רמת טבלה – לאחר הגדרת כל העמודות בטבלה מגדירים את האילוצים ומגדירים את העמודה עליה‬ ‫‪‬‬
‫חל האילוץ‪.‬‬
‫נשתמש ביצירת אילוץ ברמה זו במקרים הבאים‪:‬‬
‫‪ o‬כאשר נרצה להוסיף אילוץ על עמודה אשר מוגדר עליה אילוץ (משום שלא ניתן לבצע ברמת‬
‫עמודה יותר מאילוץ אחד לכל עמודה)‪.‬‬
‫‪ o‬כאשר האילוץ חל על שילוב עמודות‪.‬‬
‫‪ o‬כאשר יש צורך בהגדרת תנאי המבצע בדיקה של ערכים בעמודה אחת אל מול ערכים בעמודה‬
‫שניה‪.‬‬

‫מבנה‪:‬‬

‫)]…‪[CONSTRAINT constraint_nick_name] constraint_type (column_name[,column_name‬‬

‫! לפני שם אילוץ – ‪ constraint_nick_name‬תצויין המילה ‪ , CONSTRAINT‬ההמלצה‬


‫קיצור סוג אילוץ_שם העמודה_שם הטבלה‬ ‫היא מתן שם אילוץ המורכב מ‪:‬‬
‫מתן שם לאילוץ הוא אופציונלי‪.‬‬

‫! ניתן לציין ערכי ‪ DEFAULT‬או הגדרת עמודה כ ‪( NULL‬כלומר ניתן להזין ערכי ‪)NULL‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪84‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Not Null‬‬
‫תנאי המחייב הכנסת ערך לשדה‪.‬‬

‫דוגמה למבנה הכתיבה‪:‬‬

‫‪....OrderID int NOT NULL,‬‬

‫האילוץ ‪ NOT NULL‬לא ניתן להגדרה ברמת טבלה‪.‬‬

‫‪Check‬‬
‫תנאי אשר מוסיפים על עמודה‪ .‬תוצאת התנאי חייבת להיות ‪ ,true‬על מנת שהערך המוכנס יתקבל בשדה‪.‬‬
‫כל תנאי המוגדר בשאילת ‪ select‬לאחר משפט ה‪ where -‬יכול להופיע כ‪.check-‬‬

‫מבנה רמת עמודה‪:‬‬

‫)‪Column_definition [CONSTRAINT constraint_nick_name] CHECK(condition‬‬

‫מבנה רמת טבלה‪:‬‬

‫)‪[CONSTRAINT constraint_nick_name] CHECK (condition‬‬

‫דוגמה למבנה הכתיבה‪:‬‬


‫‪….CHECK (Discount >= 0 and Discount <= 1) ,‬‬

‫כפי שניתן לראות כעת ניתן להכניס לשדה ‪ discount‬ערכים ביו ‪ 0‬ל‪ 1-‬בלבד‪.‬‬

‫‪Unique‬‬
‫עמודה או מספר עמודות אשר שילובן מהווה ערך חד ערכי‪ ,‬אך העמודה או שילוב העמודות המגדירות אותו‬
‫יכולות להכיל את הערך ‪ ,NULL‬מטרת השימוש ב‪ unique -‬ליצור מפתחות קבילים נוספים שהם אינם‬
‫המפתחות הראשיים‪ ,‬שוב עבור שלמות הנתונים ושיפור ביצועיים‪.‬‬

‫מבנה רמת עמודה‪:‬‬

‫‪Column_definition [CONSTRAINT constraint_nick_name] UNIQUE‬‬

‫מבנה רמת טבלה‪:‬‬

‫)]…‪[CONSTRAINT constraint_nick_name] UNIQUE (column [,column‬‬

‫עמוד ‪85‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪ -Primary Key‬מפתח ראשי‬
‫עמודה או מספר עמודות אשר שילובן מהווה ערך חד ערכי‪ ,‬וישנה חובת הזנה‪ .‬כפי שכבר צוין‪ ,‬מטרת המפתח‬
‫הראשי להוות מזהה עבור רשומה וע"י כך למנוע כפילויות ולשפר את ביצוע שליפת הנתונים‪.‬‬

‫מבנה רמת עמודה‪:‬‬

‫‪Column_definition [CONSTRAINT constraint_nick_name] PRIMARY KEY‬‬


‫מבנה רמת טבלה‪:‬‬

‫)]…‪[CONSTRAINT constraint_nick_name] PRIMARY KEY (column [,column‬‬

‫דוגמה למבנה הכתיבה‪:‬‬

‫‪... PRIMARY KEY (OrderID,ProductID(,‬‬

‫שילוב העמודות ‪ orderid‬ו‪ productid -‬מהווה מפתח‪ ,‬שכן באותו מספר הזמנה שמייחדת הזמנת לקוח מסוים‪,‬‬
‫לא יכולות להיות שתי רשומות עבור אותו מוצר‪ .‬אם הוזמן אותו מוצר שוב‪ ,‬שדה הכמות אמור להתעדכן‪.‬‬
‫הגדרת האילוץ הנ"ל יתבצע ברמה של טבלה בלבד‪.‬‬

‫‪ - Foreign Key‬מפתח זר‬


‫עמודה או מספר עמודות בטבלה אחת המכילות ערכים המוגדרים כמפתח ראשי בטבלה האחרת‪ ,‬לדוגמה‪:‬‬
‫‪ ProductId‬בטבלת הזמנות חייב להיות ‪ ProductId‬שקיים בטבלת המוצרים שבבסיס הנתונים‪.‬‬

‫מבנה רמת עמודה‪:‬‬


‫‪Column_definition‬‬ ‫‪[CONSTRAINT‬‬ ‫]‪constraint_nick_name‬‬ ‫‪REFERENCES‬‬
‫)‪table_name(column‬‬
‫מבנה רמת טבלה‪:‬‬
‫‪[CONSTRAINT constraint_nick_name] FOREIGN KEY (Column_name) REFERENCES‬‬
‫)‪table_name(column‬‬

‫דוגמה למבנה הכתיבה‪:‬‬

‫)‪...FOREIGN KEY(ProductID) REFERENCES Products(productID‬‬

‫השדה המופיע בסוגריים הוא המפתח הזר אשר מצביע (‪ )REFERENCES‬לטבלת ‪.Products‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪86‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
:‫דוגמה להגדרת טבלת פרטי הזמנה‬
CREATE TABLE [Order Details]
(
OrderID int CONSTRAINT ord_det_ord_id_nn NOT NULL,
ProductID int NOT NULL,
UnitPrice money NOT NULL DEFAULT (0),
Quantity smallint NOT NULL DEFAULT (1),
Discount real NOT NULL DEFAULT (0),
PRIMARY KEY (OrderID,ProductID(,
FOREIGN KEY (OrderID) REFERENCES Orders,
FOREIGN KEY(ProductID) REFERENCES Products,
CHECK (Discount >= 0 and Discount <= 1),
CHECK (Quantity > 0),
CHECK (UnitPrice >= 0)
)

:‫ מבנה הפקודה המלא‬.ALTER TABLE ‫ניתן להוסיף אילוצים לטבלה קיימת על ידי שימוש ב‬

ALTER TABLE [schema.]table


] ADD / DROP / RENAME ]

:)‫הוספת אילוץ (ההוספה היא ברמת טבלה‬

ADD [CONSTRAINT constraint_nick_name] constraint_type (column)

‫ חייבת להיות ברמת שורה לכן יש לבצע שינוי של העמודה‬NOT NULL ‫! הוספת אילוץ‬
. NOT NULL ‫כולה והגדרת האילוץ‬

:‫אופציות למחיקת אילוץ‬

DROP PRIMARY KEY [CASCADE]


DROP UNIQUE (column,...)
DROP CONSTRAINT constraint_name [CASCADE]

87 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫פרק ‪View -14‬‬
‫ה‪ VIEW -‬הוא אובייקט במסד הנתונים אשר מאחסן שאילתה בבסיס הנתונים‪.‬‬

‫בכל פעם שהמשתמש פונה ל – ‪ ,VIEW‬הוא מריץ מחדש מול בסיס הנתונים‪.‬‬
‫חשוב לציין כי עבור המשתמש המפעיל שאילתות ה ‪ VIEW -‬הוא טבלה לכל דבר‪.‬‬

‫יתרונות השימוש ב ‪:VIEW -‬‬


‫‪ ‬פיקוח על המידע המוצג ל‪.user -‬‬
‫‪ ‬הסתרת מידע מגורמים שהמידע אינו רלוונטי להם‪.‬‬
‫‪ ‬הסתרת עיצוב מורכב של ה‪.database -‬‬
‫‪ ‬שיפור ביצועים‪.‬‬
‫‪ ‬מארגן מידע עבור ייצוא לאפליקציות אחרות‪.‬‬
‫‪ ‬מקל על כתיבת שאילתות מסובכות‪.‬‬

‫יצירת ‪VIEW‬‬
‫])…‪CREATE VIEW view_name [(alias,‬‬
‫‪AS‬‬
‫שאילתה‬
‫]‪[WITH CHECK OPTION‬‬
‫דוגמה‪:‬‬

‫בסיס נתונים‪.Northwind:‬‬
‫יצירת ‪ VIEW‬המציג את פרטי העובדים שיש להם איזור מוגדר(‪)REGION‬‬
‫‪CREATE VIEW emp_det_vw‬‬
‫‪AS‬‬
‫‪SELECT employeeID, lastname, firstname, birthdate‬‬
‫‪FROM employees‬‬
‫‪WHERE Region IS NOT NULL‬‬

‫הצגת הנתונים מה ‪ VIEW‬תתבצע ע"י הרצת השאילתה‪:‬‬


‫‪SELECT * FROM emp_det_vw‬‬
‫דוגמה‪:‬‬
‫בסיס נתונים‪.Northwind:‬‬
‫יצירת ‪ VIEW‬המציג פרטים לגבי הזמנות שהמשלוח שלהן לא מבוצע בזמן‪ ,‬עבור כל הזמנה כזו יוצג שם‬
‫הלקוח מספר ההזמנה ותאריך המשלוח‪.‬‬
‫‪CREATE VIEW shipStatusView‬‬
‫‪AS‬‬
‫‪SELECT o.OrderId,o.ShippedDate,c.ContactName‬‬
‫‪FROM Customers c Inner Join Orders o‬‬
‫‪ON c.CustomerId=o.CustomerId‬‬
‫‪WHERE RequiredDate<ShippedDate‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪88‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫הפעלת שאילתות ופקודות ‪ DML‬על ‪VIEW‬‬

‫ניתן להפעיל כל שאילתת ‪ select‬על ‪ VIEW‬כאילו היתה טבלה בפני עצמה‪.‬‬

‫הפעלת פקודות ‪ DML‬על ‪ VIEW‬כמו עדכון‪ ,‬הוספה ומחיקה אפשריות אך ורק במידה ו‪:‬‬
‫ניתנה למשתמש הרשאה לכך‪.‬‬ ‫‪‬‬
‫ה ‪ VIEW‬מורכב מנתונים של טבלה אחת בלבד‪.‬‬ ‫‪‬‬
‫קיימים בתצפית כל השדות המחויבים בהכנסת ערך (השדות שמוגדרים כ‪ )not Null-‬או שהוגדר‬ ‫‪‬‬
‫בטבלה המקורית ערך ברירת מחדל עבורם‪.‬‬
‫לא קיימת המילה ‪.DISTINCT‬‬ ‫‪‬‬
‫לא קיים משפט ה ‪.GROUP BY‬‬ ‫‪‬‬

‫שינוי ‪VIEW‬‬
‫])…‪ALTER VIEW view_name [(alias,‬‬
‫‪AS‬‬
‫שאילתה‬
‫‪ VIEW‬עם ‪CHECK OPTION‬‬

‫הוספה של משפט ה ‪ With Check Options‬לא יאפשר פעולות ‪ DML‬המפרות את תנאי ה ‪ WHERE -‬של‬
‫השאילתא שהגדירה את ה ‪.VIEW -‬‬
‫דוגמה‬
‫יצירת ‪ VIEW‬של מוצרים העולים פחות מ ‪ 20 -‬דולר‪.‬‬
‫‪CREATE VIEW LOW_PRICED_PRODUCTS‬‬
‫‪AS‬‬
‫* ‪SELECT‬‬
‫‪FROM Products‬‬
‫‪WHERE UnitPrice < 20‬‬
‫‪WITH CHECK OPTION‬‬

‫היות וה‪ view -‬הוגדר ‪ with check option‬אפשר לבצע כל ‪ DML‬פרט ובתנאי שלא מפרים את תנאי המחיר‬
‫כלומר‪:‬‬
‫א‪ .‬לא ניתן להכניס מוצר חדש שמחירו מעל ‪ 20‬דולר‬
‫ב‪ .‬לא ניתן לעדכן מחיר של מוצר קיים ליותר מ‪ 20‬דולר‬

‫כך למשל אפשר לבצע את העדכון הזה‪:‬‬


‫‪UPDATE low_priced_products‬‬
‫'‪SET ProductName = 'Green Tea‬‬
‫‪WHERE ProductID =1‬‬
‫אך לא ניתן לבצע את העדכון הבא‪:‬‬
‫‪UPDATE low_priced_products‬‬
‫‪SET UnitPrice = 21‬‬
‫‪WHERE ProductID =1‬‬
‫מחיקת ‪VIEW‬‬
‫‪DROP VIEW view_name‬‬

‫עמוד ‪89‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪T-SQL BASIC -15‬‬
‫שפת ה ‪ Transact-SQL‬היא שפה פרוצדורלית‪ .‬זו למעשה הרחבה של ‪ Microsoft‬לשפת ה‪SQL -‬‬
‫המאפשרת תמיכה במשתנים‪ ,‬בפונקציות‪ ,‬תנאים‪ ,‬לולאות וכד'‪.‬‬

‫בפרק זה נעסוק בפקודות הבסיסיות של ‪ T-SQL‬עמן נעבוד ונעזר בהמשך הדרך באובייקטים נוספים אשר‬
‫יילמדו בהמשך‪:‬‬
‫‪ o‬מושגי יסוד‬
‫‪ o‬הגדרת משתנים מקומיים‬
‫‪ o‬השמת ערך למשתנה מקומי (אתחול משתנה)‬
‫‪ o‬השמת ערך למשתנה מתוך משפט ‪SELECT‬‬
‫‪ o‬הדפסת משתנה‬
‫‪ o‬תנאים‬
‫‪CASE o‬‬
‫‪ o‬לולאת ‪WHILE‬‬
‫‪ o‬לולאת ‪GOTO‬‬
‫‪ o‬טיפול בשגיאות‬

‫מושגי יסוד‬

‫‪ – Batch‬אוסף פקודות הנשלחות לשרת לשם ביצוען יחדיו‪( .‬פקודות ‪ – DDL‬כל פקודה היא ‪Batch‬‬ ‫‪‬‬
‫נפרד)‬
‫‪ – GO‬מפריד בין ‪ Batch‬ל ‪ ,Batch‬כאשר משתנים אשר יוגדרו יהיו רלוונטיים לאותו ה ‪ Batch‬בלבד‪.‬‬ ‫‪‬‬
‫[ ] – למילים שמורות או רווחים בשמות טבלאות או עמודות‪.‬‬ ‫‪‬‬
‫@ ‪ -‬סימון למשתנה‪.‬‬ ‫‪‬‬
‫‪ - #‬משתנה זמני לוקאלי‪.‬‬ ‫‪‬‬
‫‪ - ##‬משתנה זמני גלובלי‪.‬‬ ‫‪‬‬
‫‪ – Shift+F1‬שימוש ב ‪ , on line help‬עזרה ספציפית‪.‬‬ ‫‪‬‬

‫הגדרת משתנים מקומיים ‪Local Variables -‬‬


‫משתנים מקומיים מוגדרים בתוך משפט ‪ SQL‬או בתוך פרוצדורה באמצעות מילת המפתח ‪.DECLARE‬‬

‫מבנה‪:‬‬

‫]…‪DECLARE @local_variable data_type [,@local_variable data_type,‬‬

‫משתנים מקומיים של ‪ Transact-SQL‬יכולים להחזיק ערך בודד אחד‪.‬‬

‫דוגמה להגדרת משתנים‪:‬‬

‫)‪DECLARE @CustomerID CHAR(5‬‬

‫)‪DECLARE @CustomerID CHAR(5), @CustomerName VARCHAR(30‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪90‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫השמת ערך למשתנה מקומי‬
‫ניתן להשים ערכים למשתנים על ידי‪:‬‬

‫שימוש ב ‪ SET‬ובכך לאתחל את המשתנה‪( .‬אתחול כל משתנה מתבצע על ידי שימוש במשפט ‪SET‬‬ ‫‪‬‬
‫בנפרד)‬
‫מבנה‪:‬‬
‫‪SET @local_variable = value‬‬

‫השמת ערך מתוך בסיס הנתונים על ידי שימוש במשפט ‪ .SELECT‬כאשר משתנים מקומיים מוגדרים‬ ‫‪‬‬
‫ב‪ select list -‬משפט ה‪ SELECT-‬חייב להחזיר שורה אחת בלבד‪.‬‬
‫‪SELECT @local_variable = column_name‬‬
‫]…‪[,@local_variable = column_name‬‬
‫‪FROM table_name‬‬
‫‪WHERE condition‬‬

‫דוגמה לשימוש ב ‪ SET‬ושימוש במשתנה במשפט ה ‪:SELECT‬‬

‫בסיס הנתונים ‪NorthWind‬‬


‫הדוגמה הבאה מגדירה משתנה מקומי ‪ ,@CustomerID‬מכניסה לתוכו ערך ומבצעת שאילתה מבסיס‬
‫הנתונים השולפת את העמודות ‪ CompanyName, ContactName, Phone‬מטבלת ‪ Customers‬עבור‬
‫אותן השורות המקיימות את התנאי שה‪ CustomerId-‬שווה למשתנה המקומי @‪.CustomerID‬‬

‫)‪DECLARE @CustomerID CHAR(5‬‬


‫'‪SET @CustomerID = 'AROUT‬‬ ‫שלב ההשמה‬

‫‪SELECT CompanyName, ContactName, Phone‬‬


‫‪FROM Customers‬‬
‫‪WHERE CustomerID = @CustomerID‬‬
‫תוצאת הרצת הקוד‪:‬‬

‫‪CompanyName‬‬ ‫‪ContactName‬‬ ‫‪Phone‬‬


‫‪------------------------ ------------------------------ ----------------------------------------‬‬
‫‪Around the Horn‬‬ ‫‪Thomas Hardy‬‬ ‫‪(171) 555-7788‬‬

‫)‪row(s) affected)1‬‬

‫עמוד ‪91‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
:SELECT ‫השמת ערך מבסיס הנתונים על ידי משפט‬
NorthWind ‫בסיס הנתונים‬
‫ משתנה זה מקבל את הערך של העמודה‬,@CustomerID ‫בדוגמה הבאה מוגדר משתנה מקומי בשם‬
‫ לאחר מכן מתבצעת השאילתה ששולפת‬.10249 ‫ עבור הזמנה שמספרה‬Orders ‫ שבטבלת‬CustomerID
‫ עבור אותן השורות‬Customers ‫ מטבלת‬CompanyName, ContactName, Phone ‫את העמודות‬
.@CustomerID ‫ שווה למשתנה המקומי‬CustomerId -‫המקיימות את התנאי שה‬

DECLARE @CustomerID CHAR(5)

SELECT @CustomerID = CustomerID ‫שלב ההשמה‬


FROM Orders
WHERE OrderID = 10249

SELECT @CustomerID

SELECT CompanyName,ContactName,Phone FROM Customers


WHERE CustomerID = @CustomerID

:‫תוצאת הרצת הקוד‬


TOMSP

(1 row(s) affected)

CompanyName ContactName Phone


Toms Spezialit‫ה‬ten Karin Josephs 0251-031259

(1 row(s) affected)

‫הדפסת משתנים‬

:‫ניתן להדפיס משתנים מקומיים‬

‫ במידת‬,‫ מקבלת ערכים מחרוזתיים בלבד‬PRINT( PRINT ‫ על ידי שימוש ב‬MESSAGE ‫בחוצץ‬ 
)CONVERT ‫ או‬CAST ‫הצורך יש לבצע המרה – שימוש ב‬
:‫מבנה‬
PRINT @local_variable

.SELECT ‫ על ידי שימוש ב‬RESULT ‫בחוצץ‬ 


:‫מבנה‬
SELECT @local_variable

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 92 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫תנאים ‪Conditions‬‬
‫שימוש במשפט ‪ IF‬מאפשר לבצע בדיקה במידה ותנאי מתקיים או לא ומהן הפקודות שיתבצעו בהתאם‪.‬‬
‫מבנה‪:‬‬
‫‪IF Boolean_expression‬‬
‫}‪{sql_statement | statement_block‬‬
‫‪[ELSE‬‬
‫]}‪{sql_statement | statement_block‬‬

‫לאחר המילה ‪ IF‬יופיע תנאי אשר לאחר בדיקתו נקבל ‪ TRUE‬או ‪ FALSE‬בלבד‪ ,‬כאשר הקוד שמצוין לאחר‬
‫מכן יתבצע במידה ותוצאת התנאי תהא ‪.TRUE‬‬
‫ניתן לצרף למשפט את המילה ‪ ELSE‬ולציין לאחריה מה יבוצע אם תוצאת התנאי תהא ‪.FALSE‬‬
‫במידה ונרצה לציין יותר מפקודה אחת יש להשתמש בבלוק‪.‬‬

‫מבנה בלוק פקודות‪:‬‬


‫‪BEGIN‬‬
‫}‪{sql_statement, statement_block‬‬
‫‪END‬‬

‫השימוש בפסוק ‪ BEGIN‬ו‪ END -‬חייב להתבצע כצמד‪ ,‬האחד לא יכול לבוא ללא השני‪ .‬משפט ה‪BEGIN -‬‬
‫מופיע בשורה משלו ואח"כ קטע של משפטי ‪ .Transact-SQL‬לבסוף מופיע משפט ה‪ END -‬בשורה משלו‬
‫המציין את סוף הבלוק‪.‬‬
‫השימוש בבלוק יתבצע בשימוש במשפטי תנאי ‪ IF -‬ולולאות – ‪.WHILE‬‬

‫דוגמה לשימוש במשפט תנאי‪:‬‬


‫בדוגמה הבאה משפט ה‪ IF-‬קובע האם המשתנה ‪ @x‬שהוגדר שווה ל‪ 1 -‬ומדפיס הודעה בהתאם‪.‬‬
‫‪DECLARE @x INT‬‬
‫‪SET @x = 1‬‬
‫(‪IF (1 = @x‬‬
‫‪BEGIN‬‬
‫' !‪PRINT 'You are number one‬‬
‫‪END‬‬
‫‪ELSE‬‬
‫‪BEGIN‬‬
‫' (‪PRINT 'Loser ;-‬‬
‫‪END‬‬

‫תוצאת הרצת הקוד‪:‬‬


‫)‪You are number one! ;-‬‬

‫במידה והמשתנה שונה מ – ‪ )@x <> 1( 1‬תוצאת הרצת הקוד תהיה‪:‬‬

‫(‪Loser ;-‬‬

‫* היות ושפת ‪ Transact-SQL‬היא הרחבה לשפת לשפת ‪ SQL‬ניתן להשתמש בה בפונקציות ואופרטורים‬
‫המוכרים מ ‪ ,SQL‬למשל ‪ EXISTS‬ו‪.CASE -‬‬

‫עמוד ‪93‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫שימוש ב – ‪ Exists‬בתנאי‬

‫‪ EXISTS‬מאפשר לבחון אם תת השאילתה החזירה שורות כלשהן ומחזירה ערך ‪ TRUE‬או ‪.FALSE‬‬

‫מבנה‪:‬‬
‫‪EXISTS subquery‬‬
‫‪Returns TRUE if a subquery contains any rows.‬‬

‫דוגמה ל ‪: EXISTS‬‬
‫בסיס הנתונים ‪NorthWind‬‬
‫הדוגמה הבאה מוחקת לקוח מרשימת הלקוחות אך טרם ביצוע הפעולה בודקת האם קיימת לו הזמנה ‪.‬‬
‫‪IF EXISTS (SELECT * FROM Orders‬‬
‫)'‪WHERE CustomerID = 'VINET‬‬
‫‪BEGIN‬‬
‫'‪PRINT 'The Customer has Order‬‬
‫‪END‬‬
‫‪ELSE‬‬
‫‪BEGIN‬‬
‫'‪DELETE Customers WHERE CustomerID = 'VINET‬‬
‫'‪PRINT 'Customer deleted‬‬
‫‪END‬‬

‫שימוש בביטויי ‪Case‬‬

‫הפונקצינ ‪ CASE‬פועלת באופן דומה לתנאי ‪ ,IF‬ואפשר להשתמש בה בקוד ‪.transact-SQL‬‬

‫להזכירך‪ CASE ,‬הוא ביטוי המספק אמצעי להחזרת נתונים שונים המבוסס על בדיקת הערך המוחזר‪.‬‬
‫ב‪ SQL-‬קימות שתי ורסיות שונות של ‪ case‬והן‪:‬‬

‫‪Simple CASE expression ‬‬


‫‪Search CASE expression ‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪94‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫דוגמה‬
‫בדוגמא הבאה המשתנה ‪ @Case_result‬מקבל מחרוזת בהתאם לערכו של ‪ , @x‬וזאת תוך שימוש ב‬
‫‪.Simple case‬‬

‫‪DECLARE‬‬
‫‪@x INT,‬‬
‫)‪@Case_result VARCHAR(20‬‬

‫‪SET @x =1‬‬
‫= ‪SET @Case_Result‬‬ ‫‪CASE @x‬‬
‫'!‪WHEN 1 THEN 'You are number one‬‬
‫'… ‪WHEN 2 THEN 'Almost‬‬
‫‪ELSE 'Loser :-(' END‬‬
‫‪PRINT @Case_Result‬‬

‫תוצאת הרצת הקוד‪:‬‬


‫!‪You are number one‬‬

‫שים לב ‪ CASE‬היא פונקצית שורה השייכת לשפת ‪ ,SQL‬זו פונקציה ‪.ANSI‬‬

‫‪@@ROWCOUNT‬‬

‫משתנה גלובלי אשר מחזיר את מספר הרשומות שהושפעו מפקודה מסויימת (‪ SELECT‬או ‪.)DML‬‬

‫עמוד ‪95‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫לולאות ‪While -‬‬

‫לולאת ‪ While‬מאפשרת ביצוע מחזורי של משפטי ‪.SQL‬‬


‫משפטי ה‪ SQL-‬מופעלים באופן מחזורי כל עוד תנאי שהוגדר מתקיים‪.‬‬

‫מבנה הלולאה‪:‬‬
‫‪WHILE‬‬ ‫‪Boolean_expression‬‬
‫‪{sql_statement‬‬ ‫|‬ ‫}‪statement_block‬‬

‫ניתן לקנן שתי לולאות ‪ While‬או יותר האחת בתוך השניה‪.‬‬

‫שימוש ב ‪break -‬‬


‫שימוש במילה ‪ break‬מאפשר להפסיק את הלולאה‪.‬‬

‫שימוש ב ‪continue -‬‬


‫שימוש ב‪ continue -‬מאפשר להפסיק את האיטרציה הנוכחית של הלולאה ומעבירנו לאיטרציה הבאה‪.‬‬

‫דוגמה ‪:‬‬
‫בסיס הנתונים ‪NorthWind‬‬
‫דוגמה לשימוש בלולאת ‪:While‬‬
‫הדוגמה הבאה מגדירה משתנה מונה בשם ‪ .@n‬הלולאה מתבצעת כל עוד המשתנה ‪ @n‬קטן או שווה למספר‬
‫הרשומות הקיימות בטבלת ‪ .Employees‬בבלוק שבתוך הלולאה מתבצע חיפוש עובד ששמו ‪ King‬שהערך‬
‫‪ EmployeeID‬שווה למשתנה המקומי המקודם בתוך הלולאה‪.‬‬
‫ברגע שהעובד נמצא או שתנאי הלולאה מפסיק להתקיים מסתיימת פעולה הלולאה‪.‬‬

‫‪DECLARE @n INT‬‬
‫‪SET @n = 1‬‬
‫‪WHILE (SELECT COUNT(*) FROM Employees) >= @n‬‬
‫‪BEGIN‬‬
‫‪IF (SELECT LastName FROM Employees‬‬
‫'‪WHERE EmployeeID = @n) = 'King‬‬
‫‪BEGIN‬‬
‫))‪PRINT 'King EmployeeID =' + CAST(@n AS VARCHAR(2‬‬
‫‪BREAK‬‬
‫‪END‬‬
‫‪ELSE‬‬
‫‪SET @n = @n + 1‬‬
‫‪END‬‬

‫תוצאת הרצת הקוד‪:‬‬


‫‪King EmployeeID = 7‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪96‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫לולאות – ‪GOTO‬‬

‫לולאת ‪ GOTO‬מאפשרת הרצה מחזורית של משפטי ה ‪ SQL‬כל עוד תנאי שהוגדר מתקיים‪.‬‬
‫אך בניגוד ללולאת ‪ ,WHILE‬הלולאה תתבצע פעם אחת לפחות והתנאי ייבדק רק לאחר הביצוע הראשון‪.‬‬
‫לולאה מסוג זה משמשת גם לביצוע פעולות אשר חוזרות על עצמן בקוד‪.‬‬

‫מבנה הלולאה‪:‬‬
‫‪Label:‬‬
‫‪Sql_statments | statement block‬‬

‫‪IF condition‬‬ ‫‪GOTO‬‬ ‫‪Label‬‬


‫דוגמה‪:‬‬
‫בסיס הנתונים ‪.NorthWind‬‬
‫בדוגמה הבאה נתחיל מעובד מספר ‪ ,4‬נדפיס את שמו ותאריך הלידה שלו‪ .‬נעבור על מספרי העובדים בקפיצה‬
‫של ערך אחד כל פעם ונבדוק האם בשם העובד קיימת האות ‪( a‬התנאי של הלולאה) ‪ .‬אם היא קיימת ‪ -‬פרטי‬
‫העובד מודפסים‪ ,‬אם היא לא – נצא מהלולאה ותודפס ההודעה‪That's how GOTO LOOP works... :‬‬

‫‪DECLARE @emp_id NUMERIC(4), @name VARCHAR(30),‬‬


‫‪@b_date DATETIME‬‬

‫‪SET @emp_id = 4‬‬

‫‪LABEL:‬‬
‫‪SELECT @name =lastname, @b_date = birthdate‬‬
‫‪FROM employees‬‬
‫‪WHERE employeeid = @emp_id‬‬
‫)‪PRINT @name + CAST(@b_date AS VARCHAR‬‬
‫‪SET @emp_id = @emp_id +1‬‬

‫‪IF @name LIKE '%a%' GOTO LABEL‬‬

‫'‪PRINT CHAR(10)+'That''s how GOTO LOOP works...‬‬

‫תוצאת הרצת הקוד‪:‬‬

‫‪PeacockSep 19 1937 12:00AM‬‬


‫‪BuchananMar 4 1955 12:00AM‬‬
‫‪SuyamaJul 2 1963 12:00AM‬‬
‫‪KingMay 29 1960 12:00AM‬‬

‫‪That's how GOTO LOOP works...‬‬

‫שים לב המילה ‪ LABEL‬אינה מילה שמורה‪ .‬ניתן להשתמש בכל רצף אותיות אחר‪.‬‬

‫עמוד ‪97‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫טיפול בשגיאות‬

‫‪Try… Catch‬‬

‫דרך לטיפול בשגיאות‪ ,‬כל המשפטים שיימצאו בתוך ה ‪ TRY‬ייבדקו וברגע שתעלה שגיאה‪ ,‬השגיאה תטופל‬
‫בתוך ה ‪.CATCH‬‬

‫מבנה‪:‬‬

‫‪BEGIN TRY‬‬

‫‪Sql statements‬‬

‫‪END TRY‬‬

‫‪BEGIN CATCH‬‬

‫‪Sql statements‬‬

‫‪END CATCH‬‬

‫דגשים‪:‬‬

‫‪ .1‬יש לציין את בלוק ה ‪ CATCH‬ישר אחרי ה ‪( END TRY‬לא ניתן להכניס משפטי ‪SELECT‬באמצע)‪.‬‬

‫‪ .2‬יש לבצע שימוש בטרנזקציות – במידה ופקודה אחת נכשלת‪ ,‬כל קודמותיה ייכשלו‪ .‬אחרת‪ ,‬חלק‬
‫מהפעולות מתבצעות ורק הפעולה עם השגיאה תטופל בהתאם ותכשל‪.‬‬

‫‪ .3‬ניתן לתפוס שגיאות שהתקבלו על ידי שימוש ב‪:‬‬

‫)(‪ – ERROR_MESSAGE‬ההודעה שהתקבלה‬


‫)(‪ – ERROR_NUMBER‬מספר השגיאה‬
‫)(‪ – ERROR_LINE‬אינדיקציה למספר השורה בה התקבלה השגיאה‬
‫)(‪ – ERROR_PROCEDURE‬הפרוצדורה בה קרתה השגיאה‬
‫)(‪ – ERROR_SEVERITY‬חומרת השגיאה‬
‫)(‪ – ERROR_STATE‬במידה ויש ‪DISTREBUTED DATE BASES‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪98‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪RAISERROR‬‬

‫דרך נוספת לטיפול בשגיאות‪ ,‬השגיאה עולה בצורה יזומה‪ .‬ניתן לשלב את משפט ה ‪ -RAISERROR‬בבלוקים‬
‫של ‪ TRY‬ו ‪.CATCH‬‬

‫‪ RAISERROR‬יוצא מהבלוק‪ SQL SERVER ,‬לא ייבצע את שאר הפעולות בבלוק‪ .‬ומציג הודעת שגיאה‬
‫בהתאם‪ RAISERROR .‬לא סוגר טרנזקציה ולא מבצע ‪!ROLLBACK‬‬

‫מבנה‪:‬‬

‫)]‪RAISERROR (message_string | message_id | variable ,severity, state [,‬‬

‫‪  MESSAGE_STRING‬ההודעה אשר תתקבל בחוצץ ה ‪message‬‬

‫‪  MESSAGE_ID‬מספר הודעה אשר נוספה בצורה ידנית על ידי ‪sp_addmessage‬‬

‫‪  VARIABLE‬משתנה אשר יכול להיות מחרוזתי ואז יכיל הודעה‪ ,‬או מספרי ויכיל מספר שגיאה‬

‫‪ – 10‬מידע בלבד‪ ,‬ללא צבע אדום‬ ‫‪ SEVERITY‬‬


‫‪ – 11-16‬שגיאות משתמש‬
‫‪ – 25 – 19‬לשימוש ‪ ,dba‬סוגר ‪connection‬‬

‫‪  STATE‬מספר לזיהוי השגיאה במיקומים שונים בקוד‪.‬‬

‫ניתן להוסיף שגיאה ידנית בשימוש ב ‪ system procedure‬אשר נקראת ‪:addmessage‬‬

‫מבנה‪:‬‬
‫‪EXEC sp_addmessage‬‬
‫‪@msgnum = value over 50000,‬‬
‫‪@severity = value between 1 and 25,‬‬
‫’‪@msgtext = ‘The message‬‬

‫צפייה בהודעות הידניות תתבצע על ידי שליפה מטבלת ‪:sys.messages‬‬

‫* ‪SELECT‬‬
‫‪FROM sys.messages‬‬
‫מחיקה של הודעה ידנית‪:‬‬

‫‪EXEC sp_dropmessage‬‬ ‫‪message_number‬‬

‫‪@@ERROR‬‬

‫משתנה גלובלי אשר מחזיר את מספר השגיאה האחרונה שהתרחשה‪.‬‬


‫‪  0‬מעיד על הצלחה‪ ,‬כל מספר אחר ‪ ‬מעיד על שגיאה‪.‬‬
‫ניתן לתחקר בתום כל פעולה האם ‪ @@ERROR‬שונה מ – ‪ , 0‬במידה וכן – יש לבצע טיפול בהתאם‪.‬‬
‫* בגירסאת ‪ 2005‬מומלץ להשתמש ב )(‪ @@ERROR .ERROR_NUMBER‬משמש לתמיכה לאחור‬
‫בגרסא קודמת‪.‬‬

‫עמוד ‪99‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרק ‪Stored procedure -16‬‬
‫‪ - Stored Procedure‬אוסף מהודר (‪ )compiled collection‬של הצהרות ‪ SQL‬המאוחסנות יחד כאובייקט‬
‫בעל שם בודד בתוך מסד נתוני ‪.SQL Server‬‬
‫פרוצדורות יכולות להכיל‪:‬‬
‫א‪ .‬הצהרות ‪.SQL‬‬
‫ב‪ .‬הצהרות ‪ - Transact SQL‬הרחבה של ‪ Microsoft‬לשפת ה‪ ,SQL -‬כגון‪ :‬תמיכה במשתנים‪ ,‬בפונקציות‪,‬‬
‫תנאים‪ ,‬לולאות וכד'‪.‬‬

‫נקודות חשובות לגבי ‪Stored Procedures‬‬

‫‪ .1‬הפרוצדורות עוברות הידור פעם אחת‪.‬‬


‫‪ .2‬ניתן לקרוא לפרוצדורה מפרוצדורות אחרות (עד ‪ 32‬רמות‪ ,‬פרוצדורה פנימית מכירה את האובייקטים‬
‫שיצרה הפרוצדורה החיצונית)‪.‬‬
‫‪ .3‬ניתן להעביר פרמטרים לפרוצדורות‪.‬‬

‫יתרונות ‪Stored Procedures‬‬

‫הפרוצדורות מאפשרות שיתוף קוד עבור אפליקציות שונות‪ .‬כל שינוי מתבצע פעם אחת ואין צורך לעדכן‬ ‫‪.1‬‬
‫כל אפליקציה בנפרד‪.‬‬
‫חוסך מה‪ user -‬להכיר את מבנה ה‪ ,database-‬הפעולות עבורו מבוצעות דרך הפרוצדורה‪.‬‬ ‫‪.2‬‬
‫משתמש יכול לקבל הרשאה להריץ פרוצדורה בעוד אין לו הרשאה לגשת לטבלאות ותצפיות בסיס‬ ‫‪.3‬‬
‫הנתונים‪.‬‬
‫פרוצדורות משפרות ביצועים‪.‬‬ ‫‪.4‬‬
‫פרוצדורות מורידות עומס מהרשת שכן במקום לשלוח מספר הוראות כל אחת בנפרד ולקבל משוב על כל‬ ‫‪.5‬‬
‫אחת מהן‪ ,‬נשלחת בקשה אחת ותגובה אחת‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪100‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫יצירת פרוצדורה‬

‫קוד הפרוצדורה ‪ AS‬שם הפרוצדורה ‪CREATE PROCEDURE‬‬

‫דוגמה‪:‬‬
‫בסיס הנתונים‪NorthWind :‬‬
‫‪CREATE PROCEDURE getEmployees AS‬‬
‫‪Select * from employees‬‬

‫*שים לב כי הדוגמה היא פשוטה לצורך הכרת סינטקס הכתיבה ‪ ,‬אך כפי שצוין קודם הפרוצדורה יכולה להכיל‬
‫קוד מורכב יותר שאתה כבר מכיר‪ ,‬ותוספות שנכיר בהמשך‪.‬‬

‫בסיום הכתיבה יש להריץ את הקוד על מנת לאחסן את הפרוצדורה בבסיס הנתונים‪.‬‬

‫! יש לשים לב כי הרצת הקוד יוצרת את הפרוצדורה ולא מריצה אותה! כדי להריץ את הפרוצדורה נבצע‬
‫‪ EXECUTE‬לפרוצדורה‪.‬‬

‫הרצת פרוצדורה‬
‫שם הפרוצדורה ]‪EXE[CUTE‬‬
‫דוגמה‪:‬‬
‫בסיס הנתונים‪NorthWind :‬‬
‫הרצת הפרוצדורה ‪:getEmployees‬‬

‫‪EXECUTE getEmployees‬‬

‫*אם מורצת אך ורק פרוצדורה ניתן לכתוב את שמה בלבד‪.‬‬

‫מחיקת פרוצדורה‬
‫שם הפרוצדורה ‪DROP PROCEDURE‬‬

‫דוגמה‪:‬‬
‫בסיס הנתונים ‪NorthWind‬‬
‫מחיקת הפרוצדורה ‪getEmployees‬‬
‫‪DROP PROCEDURE getEmployees‬‬

‫עמוד ‪101‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫שילוב פקודות ‪ DML‬בפרוצדורה‬

‫ניתן לשלב פרוצדורות ופקודות ‪ DML‬אשר ייבצעו מניפולציה על הנתונים בטבלה‪.‬‬

‫דוגמה‪:‬‬
‫שילוב פרוצדורה ופקודת ‪.INSERT‬‬
‫הדוגמה הבאה מכניסה את העובדים שהועסקו עד היום (לא כולל) לטבלת הלקוחות‪.‬‬

‫הפרוצדורה בוחרת את העובדים המתאימים‪:‬‬

‫‪CREATE PROCEDURE EmployeeCustomer‬‬


‫‪AS‬‬
‫‪SELECT upper(substring(LastName,1,4)+substring(FirstName,1,1)),‬‬
‫‪’Northwind Traders’, rtrim(FirstName)+' '+‬‬
‫‪LastName,’employee’,Address, City ,Region , PostalCode ,‬‬
‫‪country ,(‘(206) 555-1234’+’ x’+extension), NULL‬‬
‫‪FROM employees‬‬
‫)(‪WHERE HireDate<GETDATE‬‬

‫ובהרצת הקוד משלבת שאילתה נוספת המבצעת את הכנסת הנתונים לטבלה האחרת‪:‬‬

‫‪INSERT INTO Customers‬‬


‫‪EXEC EmployeeCusromer‬‬

‫* ניתן גם לבצע את פקודת ה ‪ DML‬בפרוצדורה עצמה‪.‬‬

‫שינוי פרוצדורה‬

‫מבנה‪:‬‬
‫שם הפרוצדורה ‪ALTER PROCEDURE‬‬
‫‪AS‬‬
‫קוד הפרוצדורה החדש‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪102‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫שימוש בפרמטרים ב ‪Stored Procedure -‬‬
‫ב ‪ Stored Procedure‬ניתן להשתמש בפרמטרים‪ .‬ניתן לשלוח ערכים לפרוצדורה על ידי שימוש בפרמטרי‬
‫‪ INPUT‬וניתן לקבל חזרה ערכים על ידי שימוש בפרמטרי ‪.OUTPUT‬‬

‫הגדרת פרוצדורה המקבלת פרמטרים (‪)INPUT‬‬


‫פרוצדורה תקבל פרמטרים לאחר הגדרת שמה (הפרמטרים יכולים להופיע בסוגריים אך אין זו‬ ‫‪‬‬
‫חובה)‪.‬‬
‫לפני שם כל פרמטר יופיע הסימן @ ולאחריו יצוין סוג ה‪ DataType-‬שלו‪.‬‬ ‫‪‬‬
‫הפרמטרים יכולים לקבל ערך ברירת מחדל ואף ערך ‪ ,NULL‬במידה והוגדר ערך ברירת מחדל‬ ‫‪‬‬
‫לפרמטר המשתמש לא יהיה חייב לשלוח ערך עבור פרמטר זה‪.‬‬
‫פרמטר מסוג זה הוא פרמטר ברירת המחדל‪.‬‬ ‫‪‬‬

‫מבנה הגדרת פרמטר‪:‬‬


‫]‪@parameter data_type [=default‬‬

‫הרצת פרוצדורה עם פרמטרים‬


‫אופן ההרצה ע"י ציון הפרוצדורה ולאחריה הערכים המועברים אליה או ציון הפרוצדורה וצמדים של פרמטרים‬
‫וערכיהם‪.‬‬
‫במידה ומעבירים רשימת ערכים בלבד מחויב כי סדר הופעתם יהיה תואם לפרוצדורה המצפה לקבלם‪.‬‬

‫דוגמה לפרוצדורה עם פרמטר ‪: INPUT‬‬


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

‫‪CREATE PROCEDURE ShippedByDate‬‬


‫‪( @beginningDate dateTime,‬‬
‫)‪@EndingDate DateTime‬‬
‫‪As‬‬
‫‪IF @BeginningDate Is NULL OR @EndingDate IS NULL‬‬
‫‪Begin‬‬
‫)’‪PRINT(‘Null Values are not Allowed‬‬
‫‪RETURN‬‬
‫‪End‬‬

‫‪SELECT ShippedDate, OrderId‬‬


‫‪FROM Orders‬‬
‫‪WHERE shippedDate between @beginningDate and @endingDate‬‬

‫הרצת הפרוצדורה‪:‬‬
‫'‪EXEC ShippedByDate '12-01-96','12-31-96‬‬

‫עמוד ‪103‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
:DML ‫ ופקודת‬INPUT ‫דוגמה לפרוצדורה עם פרמטרי‬
.Northwind:‫בסיס נתונים‬
.‫בדוגמה נכתבת פרוצדורה המוסיפה לקוח חדש לטבלת הלקוחות‬

:‫הפרוצדורה‬
CREATE PROCEDURE AddCustomer
(
@CustomerId nchar(5),
@CompanyName nvchar(40)
@ContactName nvarchar (30) =NULL,
@ContactTitle nvarchar (30) =NULL,
@Address nvarchar (60) =NULL,
@City nvarchar (15) =NULL,
@Region nvarchar (15)= NULL,
@PostalCode nvarchar (10)= NULL,
@Country nvarchar (15)= NULL,
@Phone nvarchar (24) =NULL,
@Fax nvarchar (24)= NULL
)
AS
INSERT INTO Customers
VALUES (@CustomerId, @CompanyName,@ ContactName,@ContactTitle,
@ Address,@ City,@ Region,@ PostalCode,@ Country,
@Phone,@ Fax)

‫הרצת הפרוצדורה‬

:'‫דרך א‬

EXEC AddCustomer ‘ALFKI2’,’Alfreds Futterkiste’ , ‘Maria Anders’,


’Sales Representive’,’Obere Str .57’ ,
’Berlin’,Null,12209,’Germany’,’030-0074321’,Null

:'‫דרך ב‬
.)‫ציון הפרמטרים אליהם מועברים הערכים ולא בהכרח כל הערכים (במידה ומוגדר להם ערך ברירת מחדל‬
EXEC AddCustomer
@CustomerId=’ALFAKI’,
@ContactName=’Maria Anders’,
@CompanyName=’Alfreds Futterkiste’,
@ContactTitle = ’Sales Representive’,
@Address= ’Obere Str .57’,
@City = ’Berlin’,
@Region = Null,
@PostalCode = 12209,
@Country = ’Germany’,
@Phone = ’030-0074321’,
@Fax = Null

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 104 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫החזרת פרמטרים מפרוצדורה (‪)OUTPUT‬‬
‫פרוצדורה יכולה להחזיר פרמטרים לתכנית הקוראת‪.‬‬
‫פרמטר מוחזר (‪ )OUTPUT‬יוגדר כמו פרמטר ה ‪ INPUT‬רק שלאחר ציון הסוג שלו (‪ )data type‬תצוין המילה‬
‫‪.OUTPUT‬‬

‫מבנה הגדרת פרמטר‪:‬‬

‫‪@parameter data_type OUTPUT‬‬

‫דוגמה לפרוצדורה עם פרמטר ‪:OUTPUT‬‬


‫בסיס נתונים‪.Northwind:‬‬
‫הפרוצדורה מקבלת שני מספרים ומחשבת את מכפלתם‪.‬‬
‫‪CREATE PROCEDURE MathMult‬‬
‫‪@m1 smallint,‬‬
‫‪@m2 smallint,‬‬
‫‪@result smallint OUTPUT‬‬
‫‪AS‬‬
‫‪SET @ result =@m1*@m2‬‬

‫הרצת הפרוצדורה‪:‬‬
‫מאחר והפרוצדורה מחזירה ערך‪ ,‬חובה להגדיר משתנה אשר יקבל את הערך אותו מחזירה הפרוצדורה‪.‬‬
‫ניתן להדפיס את הערך החוזר על ידי שימוש ב ‪ SELECT‬או ‪.PRINT‬‬

‫‪DECLARE @answer smallint‬‬ ‫הצהרה על משתנה אשר יקבל את הערך המוחזר‪‬‬

‫‪EXEC MathMult 5,6,@answer OUTPUT‬‬ ‫הרצת הפרוצדורה ‪‬‬

‫‪SELECT 'The result is : ' ,@answer‬‬ ‫הדפסת הפרוצדורה‪‬‬

‫התוצאה המתקבלת מהרצת הקוד‪:‬‬

‫‪The result is : 30‬‬

‫עמוד ‪105‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫החזרת נתונים ע"י קוד החזרה ‪RETURN -‬‬
‫ניתן להחזיר ערכים כקוד החזרה מפרוצדורה ע"י שימוש במילה ‪.RETURN‬‬
‫יש להימנע מהחזרת קוד ‪ NULL‬ומספרים שליליים שכן אלו הם קודי שגיאה שמורים של המערכת‪.‬‬

‫דוגמה לשימוש ב ‪:RETURN‬‬


‫בסיס הנתונים ‪Pubs‬‬
‫הפרוצדורה בודקת האם קיים סופר מסוים בבסיס הנתונים בטבלת ‪ , Authors‬במידה והסופר קיים מוחזר‬
‫הערך ‪ 1‬אחרת ‪.0‬‬

‫‪CREATE PROCEDURE checkAuthor‬‬


‫‪@AuFName varchar(20),‬‬
‫)‪@AuLName varchar(40‬‬
‫‪AS‬‬
‫* ‪IF EXISTS (SELECT‬‬
‫‪FROM Authors‬‬
‫‪WHERE au_fname=@AuFName‬‬
‫)‪AND au_lname=@AuLName‬‬
‫)‪RETURN (1‬‬
‫‪ELSE‬‬
‫)‪RETURN(0‬‬

‫הרצת הפרוצדורה‪:‬‬

‫הרצת הפרוצדורה מחייבת הגדרת משתנה שיקלוט את הערך המוחזר‪ ,‬שוב הפניה אליו בעזרת משפט‬
‫‪.SELECT‬‬

‫‪DECLARE @returnCode int‬‬


‫'‪EXEC @returnCode=CheckAuthor 'Johnson', 'White‬‬

‫‪SELECT @returnCode‬‬

‫כתוצאה מהרצת הקוד יתקבל‪:‬‬


‫‪1‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪106‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪System procedure‬‬
‫פרוצדורות מערכת המבצעות פעולות אדמיניסטרטיביות רבות ושמורות בבסיס הנתונים ‪ .master‬פרוצדורות‬
‫אלה מזוהות על ידי השם התחילי ‪ _sp‬ודומות לפרוצדורות בשפות תכנות אחרות בכך שהן מקבלות פרמטרים‬
‫עבור הפונקציות מחזירות ערכים וכד'‪.‬‬

‫)‪sp_help (T-SQL‬‬
‫פרוצדורת מערכת המספקת מידע עבור האובייקטים בבסיס הנתונים‪.‬‬
‫אם נרשום ‪ sp_help‬בלבד נקבל את כל המידע שניתן לשאוב ע"י פרוצדורה זו‪.‬‬

‫‪EXEC sp_help‬‬
‫על מנת לקבל מידע ספציפי נשתמש בכתיבת הקוד‪:‬‬

‫שם האובייקט שאנו רוצים לקבל לגביו מידע ‪EXEC sp_help‬‬

‫דוגמה‪:‬‬

‫כאשר אנו נמצאים בבסיס הנתונים ‪ NorthWind‬ונפעיל את הפרוצדורה באופן הבא‪:‬‬

‫‪EXEC Sp_help Orders‬‬


‫נקבל מידע לגבי מבנה אובייקט הטבלה ‪.Orders‬‬
‫התוצאה‪:‬‬

‫‪Name Owner‬‬ ‫‪Type‬‬ ‫‪Created_datetime‬‬


‫‪----------- --------‬‬ ‫‪------------- -----------------------‬‬
‫‪Orders dbo‬‬ ‫‪user table 1998-11-13 03:11:18.517‬‬

‫‪Column_name‬‬ ‫‪Type‬‬ ‫‪Length‬‬ ‫‪Nullable‬‬


‫‪------------------‬‬ ‫‪---------‬‬ ‫‪------‬‬ ‫‪--------‬‬
‫‪OrderID‬‬ ‫‪int‬‬ ‫‪4‬‬ ‫‪no‬‬
‫‪CustomerID‬‬ ‫‪nchar‬‬ ‫‪10‬‬ ‫‪yes‬‬
‫‪EmployeeID‬‬ ‫‪int‬‬ ‫‪4‬‬ ‫‪yes‬‬
‫‪OrderDate‬‬ ‫‪datetime‬‬ ‫‪8‬‬ ‫‪yes‬‬
‫‪RequiredDate‬‬ ‫‪datetime‬‬ ‫‪8‬‬ ‫‪yes‬‬
‫‪ShippedDate‬‬ ‫‪datetime‬‬ ‫‪8‬‬ ‫‪yes‬‬
‫‪ShipVia‬‬ ‫‪int‬‬ ‫‪4‬‬ ‫‪yes‬‬
‫‪Freight‬‬ ‫‪money‬‬ ‫‪8‬‬ ‫‪yes‬‬
‫‪ShipName‬‬ ‫‪nvarchar‬‬ ‫‪80‬‬ ‫‪yes‬‬
‫‪ShipAddress‬‬ ‫‪nvarchar‬‬ ‫‪120‬‬ ‫‪yes‬‬
‫‪ShipCity‬‬ ‫‪nvarchar‬‬ ‫‪30‬‬ ‫‪yes‬‬
‫‪ShipRegion‬‬ ‫‪nvarchar‬‬ ‫‪30‬‬ ‫‪yes‬‬
‫‪ShipPostalCode‬‬ ‫‪nvarchar‬‬ ‫‪20‬‬ ‫‪yes‬‬
‫‪ShipCountry‬‬ ‫‪nvarchar‬‬ ‫‪30‬‬ ‫‪yes‬‬

‫‪Identity‬‬ ‫‪Seed‬‬ ‫‪Increment‬‬


‫‪------------- ------- ----------‬‬
‫‪OrderID 1‬‬ ‫‪1‬‬

‫עמוד ‪107‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫נספחים‬

‫ניתוח ועיצוב מודל הנתונים‬

‫כפי שכבר ציינו כל מערכת מידע מנהלת אוסף כלשהו של נתונים‪.‬‬


‫את מאגר הנתונים יש לבנות בצורה חכמה ויעילה‪ ,‬כך שתתאפשר גישה קלה לנתונים‪ ,‬שכל המידע יכלל‬
‫במערכת‪ .‬ביצועיה יהיו יעילים ומהירים‪ ,‬לא תהיה כפילות מידע וכמובן שמידע לא יאבד‪ .‬על המערכת להיות‬
‫יציבה‪ ,‬אמינה ועונה על צרכי המשתמש בה‪.‬‬
‫בשל המורכבות הרבה והדרישות שהמערכת תצטרך לספק כמו בכל דבר אחר דרושים הכנה ותכנון מקדים‬
‫מעמיק‪.‬‬
‫נהוג לתאר את המערכת טרם הקמתה בעזרת מודל נתונים )‪.(Data Model‬‬
‫מודל נתונים הוא כלי תפיסתי ורעיוני‪ ,‬המשמש לתיאור המציאות שאמורה לייצג המערכת‪.‬‬
‫המודל משמש אותנו בשלב עיצוב בסיס הנתונים כשם שתרשימי ‪ )Data Flow Diagram( DFD‬משמשים את‬
‫התוכניתן בבני ית תוכנה‪ ,‬הוא מסגרת לוגית המתארת את הישויות‪ ,‬התכונות והקשרים המייצגים את המציאות‪.‬‬
‫המודל קובע את המבנה והשמות הלוגיים של המרכיבים השונים אשר בהמשך ניצוק לתוכם את התוכן שהוא‬
‫למעשה המידע שאנו מעונינים לשמור במערכת‪.‬‬

‫במודל קיימת התייחסות לשלושה היבטים עיקריים‪:‬‬

‫הגדרת המבנה‬
‫קביעה מי הן הישויות הפועלות‪ ,‬אילו תכונות יש להם ומה הקשרים ביניהן‪.‬‬

‫הגדרת אילוצי המערכת – ‪Constraints‬‬


‫בחלק זה נקבעים אילוצים שתקיים המערכת‪ ,‬לדוגמה‪ :‬זיהוי של מספרי עובדים ‪ -‬לא יתכן שיהיו שני עובדים‬
‫בעלי אותו מספר; במידה והמערכת שומרת ציוני תלמידים לא יתכן כי יהיה ציון גבוה מ‪ 100 -‬או מספר שלילי‪,‬‬
‫וכד'‪.‬‬

‫הגדרת אוסף אופרטורים‬


‫בחלק זה קובעים את הפעולות הדינאמיות שיוכלו להתבצע על בסיס הנתונים‪ ,‬כגון שליפת נתונים‪ ,‬עדכון וכד'‪.‬‬

‫בניתוח המערכת נהוג ליצור מספר מודלים טרם קבלת המוצר הסופי המודלים‪ ,‬מתייחסים ל‪ 3 -‬שלבים בתהליך‬
‫הניתוח של המערכת והם‪:‬‬
‫שלב העיצוב התפיסתי‪ -‬שלב העוסק בעיצוב מבנה המידע ללא מגבלות ואילוצים הנובעים משימוש בחומרה‬
‫ותוכנה ‪ -‬שלב זה מייצג את כל הדרישות שבאו לידי ביטוי בניתוח דרישות המערכת‪.‬‬
‫שלב העיצוב הלוגי – שלב העוסק בתרגום המבנה התפיסתי שהתקבל למבנה של מערכת בסיסי נתונים‬
‫מסוימת‪ .‬בשלב זה כבר מתיי חסים למגבלות ויכולות בסיס הנתונים שנבחר‪ ,‬לדוגמה בסיס נתונים ‪ DB2‬של‬
‫‪ Oracle Server ,IBM‬של ‪ SQL ,Oracle‬ו‪ Access-‬של ‪.Microsoft‬‬
‫שלב העיצוב הפיסי ‪ -‬שלב בו מבצעים תרגום של הסכימה שנוצרה בשלב הקודם למבנה פיזי ‪ -‬חלוקה לטבלאות‬
‫הגדרת אינדקסים וכד'‪ .‬שים לב כי מבנה זה כבר לוקח בחשבון אילוצים ומוגדר בהתאם לכך‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪108‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫יש לציין כי התהליך הוא איטרטיבי וחוזר על עצמו וגם לאחר שסיימנו להגדיר מודל מסוים קיימת סבירות‬
‫שנצטרך לשנותו‪.‬‬

‫אחד המודלים הנפוצים לשלב העיצוב התפיסתי הוא מודל ישויות הקשרים‪ E-R -‬בו נדון בהרחבה‪.‬‬

‫)‪E-R(Entity Relationship Model‬‬


‫מודל ישויות קשרים – מודל ‪ – E-R‬המודל שפותח ע"י ‪ Peter Chen‬בשנת ‪ 1976‬ומאז משמש כלי חשוב‬
‫בעבודת מנתח מערכת בסיס הנתונים‪.‬‬
‫המודל מי יצג את העולם הממשי כאוסף של אובייקטים בסיסיים‪ ,‬המכונים ישויות (‪ )entities‬ושל יחסים בין‬
‫אובייקטים אלה‪ ,‬המכונים קשרים (‪ .) relationships‬המודל מספק כלי לתיכון בסיס נתונים באמצעות תיאור‬
‫תבנית של המידע בארגון‪ -‬תבנית ‪.E-R‬‬
‫תבנית ‪ E-R‬מציגה את המבנה הלוגי הכולל של בסיס הנתונים‪.‬‬

‫מושגים במודל‪:‬‬
‫ישות‬
‫ישות היא אובייקט מוחשי או מופשט שיש עליו מידע והוא נתון להבחנה משאר האובייקטים‪ .‬לישות יש קיום‬
‫במציאות והיא בעלת משמעות ועניין בהקשר מסוים‪.‬‬
‫לדוגמה‪ :‬משה כהן בעל תעודת זהות ‪ 01234567‬הוא ישות‪ ,‬כיוון שתיאור זה מזהה אדם אחד מסוים‪ .‬באופן‬
‫דומה חשבון מספר ‪ 123456‬בסניף השרון בבנק הפועלים הוא ישות‪ ,‬כי זהו תאור של חשבון אחד מסוים‪.‬‬
‫ישות יכולה להיות ממשית כמו אדם או ספר‪ ,‬או מופשטת כמו חופשה או רעיון‪.‬‬

‫קבוצת ישויות (‪)entity set‬‬


‫קבוצת ישויות היא קבוצה של כל הישויות מאותו סוג‪ .‬לדוגמה‪ ,‬אפשר להגדיר את קבוצת כל בעלי החשבונות‬
‫בבנק כקבוצת ישויות לקוח‪ .‬באופן דומה‪ ,‬קבוצת הישויות חשבון מייצג את קבוצת כל החשבונות המתנהלים‬
‫בבנק‪.‬‬
‫קבוצות ישויות שונות אינן מהוות בהכרח קבוצות זרות‪ .‬למשל‪ ,‬אפשר להגדיר קבוצת ישויות של כל העובדים‬
‫בבנק – עובד‪ ,‬וקבוצת ישויות אחר של כל לקוחות הבנק – לקוח‪ .‬אדם מסוים (עובד שהוא גם לקוח) יכול להיות‬
‫ישות השייכת לשתי קבוצות‪ -‬ישויות אלו גם יחד‪.‬‬

‫תכונות (‪)attributes‬‬
‫קבוצת ישויות מיוצגת באמצעות קבוצה של תכונות‪ .‬לדוגמה‪ ,‬תכונות אפשריות לקבוצת הישויות לקוח הן‪ :‬שם‪,‬‬
‫שם משפחה‪ ,‬תעודת זהות‪ ,‬גיל‪ ,‬רחוב עיר וטלפון‪.‬‬

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

‫קשר (‪)relationship‬‬
‫קשר הוא יחס בין כמה ישויות‪ .‬לדוגמה‪ :‬אפשר להגדיר קשר בין הלקוח משה לחשבון ‪ 123456‬ולבטא בכך‬
‫את העובדה שהלקוח משה הוא בעל חשבון מספר ‪.123456‬‬

‫עמוד ‪109‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫טיפוסי קשרים (‪)relationship set‬‬
‫בבניית מודל ישויות‪-‬קשרים‪ ,‬הישוי ות הבודדות הופכות לקבוצות ישות שונות והקשרים בין הישויות הופכים‬
‫לקבוצת קשר‪ .‬קבוצת קשר מוגדרת כאוסף של כל הקשרים בעלי אותה משמעות בין הישויות השונות‪.‬‬

‫מעלה של קשר‬
‫מספר הישויות המשתתפות בקשר‪.‬‬

‫תלויות בין טיפוסי ישויות‬


‫קיימות ישויות התלויות בישויות אחרות כך שללא הישויות האחרות אין להן קיום‪.‬‬
‫ישות תלויה נקראת ישות חלשה‪ ,‬בעוד ישות שתלויים בה נקראת ישות חזקה‪.‬‬
‫דוגמה לישות חלשה‪ :‬פעולה בחשבון‪ ,‬ישות זו תלויה בישות חשבון‪ ,‬שכן ללא הישות חשבון אין היא קיימת‪.‬‬

‫מידת ריבוי של קשר‬

‫כפי שכבר ציינו בין ישויות שונות יכולים להיות קשרים ‪ ,‬הקשרים מתחלקים למספר סוגים‪.‬‬

‫סוגי קשרים‬
‫‪One-To-One‬‬
‫קשר אחד לאחד מסומן ‪ .1:1‬ישות אחת מטיפוס ‪ A‬קשורה לכל היותר לישות אחת מטיפוס ‪ .B‬ישות אחת‬
‫מטיפוס ‪ B‬קשורה לכל היותר לישות אחת מטיפוס ‪.A‬‬

‫)‪One-to-One (1:1‬‬

‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪110‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪One-To-many‬‬
‫קשר אחד לרבים מסומן ‪ .N:1‬ישות אחת מטיפוס ‪ A‬קשורה למספר כלשהו של ישויות מטיפוס ‪ .B‬ישות אחת‬
‫מטיפוס ‪ B‬קשורה לכל היותר לישות אחת מטיפוס ‪.A‬‬

‫)‪One-To-Many (1:N‬‬

‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬

‫‪Many-To-One‬‬
‫קשר רבים לאחד מסומן ‪ N:1‬ישות אחת מטיפוס ‪ A‬קשורה לכל היותר לישות אחת מטיפוס ‪ .B‬ישות אחת‬
‫מטיפוס ‪ B‬קשורה למספר כלשהו של ישויות מטיפוס ‪.A‬‬

‫)‪Many-To-One (N:1‬‬

‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬

‫עמוד ‪111‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Many-To-Many‬‬

‫קשר רבים לרבים מסומן ‪ .M:N‬ישות אחת מטיפוס ‪ A‬קשורה למספר כלשהו של ישויות מטיפוס ‪ .B‬ישות אחת‬
‫מטיפוס ‪ B‬קשורה למספר כלשהו של ישויות מטיפוס ‪.A‬‬

‫‪Many-To-Many‬‬

‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪a‬‬
‫‪b‬‬
‫‪b‬‬
‫‪a‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪112‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫דיאגרמת ‪E-R‬‬
‫נהוג לתאר מבנה לוגי של בסיס הנתונים באמצעות דיאגרמת ישויות קשרים (דיאגרמת‬
‫‪ .) E -R‬דיאגרמה זו מורכבת מהרכיבים הבאים‪ ,‬כאשר בכל רכיב מצוין שם הטיפוס או שם התכונה שהוא‬
‫מייצג‪.:‬‬
‫‪.1‬מלבנים ‪ -‬מייצגים טיפוסי ישויות‪.‬‬
‫‪.2‬אליפסות ‪ -‬מייצגות תכונות‪.‬‬
‫‪.3‬מעוינים ‪ -‬מייצגים טיפוס י קשרים בין טיפוסי הישויות‪.‬‬
‫‪.4‬קווים‪ ,‬מקשרים בין טיפוסי הישויות לתכונות שלהם‪ ,‬ובין טיפוסי ישויות לטיפוסי‬
‫קשרים‪.‬‬
‫‪.5‬כל רכיב נושא תווית של הישות או הקשר אותו הוא מייצג‪.‬‬
‫‪.6‬ישות נשלטת (חלשה) תיוצג ע"י ריבוע עם דפנות כפולים‪.‬‬

‫‪social-security‬‬ ‫‪customer-street‬‬
‫‪balance‬‬

‫‪account-number‬‬
‫‪customer-‬‬
‫‪name‬‬ ‫‪customer-city‬‬

‫‪customer‬‬ ‫‪deposit‬‬ ‫‪account‬‬


‫‪or‬‬

‫מפתחות‬
‫כפי שראינו ‪ -‬קבוצת ישות אחת יכולה להיות בעלת מספר בלתי מוגבל של מופעים‪ ,‬ועל כן כדי להבדיל בין‬
‫הישויות השונות השייכות לאותה קבוצת ישויות יש להשתמש במפתח‪.‬‬
‫מפתח ‪ -‬קבוצת תכונות המאפיינת ומזהה באופן חד ערכי ישות מסוימת‪.‬‬
‫סוגי המפתחות המזהים הקיימים‪:‬‬
‫מפתח על ‪ -‬מפתח המכיל קבוצת תכונות שערכיה מייחדים ישות‪.‬‬
‫מפתח קביל ‪ -‬מפתח על‪ ,‬שאף תת קבוצה שלו אינה מפתח על‪.‬‬
‫מפתח ראשי ‪ -‬מפתח קביל שנבחר ע"י מתכנן היישום‪.‬‬

‫דוגמה‪ :‬מספר תעודת זהות ‪ -‬מזהה בן אדם אחד בלבד‪.‬‬


‫מבחינה גרפית המפתח הראשי במודל יסומן ע"י קו תחתי תחת התכונה או התכונות שהוא כולל‪.‬‬
‫בניית בסיס נתונים‬

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

‫עמוד ‪113‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫נניח כי אנו בונים מערכת למעקב אחר תלמידים הלומדים בקורסים שונים באוניברסיטה ואנו מעונינים לשמור‬
‫את סכמת הנתונים‪ -‬פרטי קורס )‪ (Course_details‬המכילה את המידע הבא‪:‬‬

‫‪Course_id‬‬ ‫_‪Course‬‬ ‫_‪Professor‬‬ ‫_‪Professor‬‬ ‫_‪Student‬‬ ‫_‪Student‬‬ ‫‪Grad‬‬


‫‪name‬‬ ‫‪name‬‬ ‫‪id‬‬ ‫‪Name‬‬ ‫‪id‬‬ ‫‪e‬‬
‫‪10455‬‬ ‫‪Consumer‬‬ ‫‪Dani Levi‬‬ ‫‪025‬‬ ‫‪Eyal Levin‬‬ ‫‪014‬‬ ‫‪96‬‬
‫‪Behavior‬‬
‫‪Hadas‬‬ ‫‪015‬‬ ‫‪100‬‬
‫‪Grossman‬‬
‫‪20144‬‬ ‫‪DataBase‬‬ ‫‪Liat‬‬ ‫‪036‬‬ ‫‪Hilla‬‬ ‫‪236‬‬ ‫‪87‬‬
‫‪system‬‬ ‫‪Barel‬‬ ‫‪Zimerman‬‬
‫‪Youval‬‬ ‫‪015‬‬ ‫‪76‬‬
‫‪Perlmoter‬‬
‫‪Eran Lefler‬‬ ‫‪258‬‬ ‫‪80‬‬

‫‪Nahama stiv‬‬ ‫‪231‬‬ ‫‪63‬‬

‫‪Hadas‬‬ ‫‪015‬‬ ‫‪84‬‬


‫‪Grossman‬‬

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

‫כתוצאה מכך המידע יאורגן מחדש ויוצג באופן הבא‪:‬‬

‫‪Course_id‬‬ ‫‪Professor_id‬‬ ‫‪Student_id‬‬ ‫‪grade‬‬


‫‪10455‬‬ ‫‪025‬‬ ‫‪014‬‬ ‫‪96‬‬
‫‪10455‬‬ ‫‪025‬‬ ‫‪015‬‬ ‫‪100‬‬
‫‪20144‬‬ ‫‪036‬‬ ‫‪236‬‬ ‫‪87‬‬
‫‪20144‬‬ ‫‪036‬‬ ‫‪015‬‬ ‫‪76‬‬
‫‪20144‬‬ ‫‪036‬‬ ‫‪258‬‬ ‫‪80‬‬
‫‪20144‬‬ ‫‪036‬‬ ‫‪231‬‬ ‫‪63‬‬
‫‪20144‬‬ ‫‪036‬‬ ‫‪015‬‬ ‫‪84‬‬

‫כעת ניתן לראות כי אפשר לזהות כל רשומה‪( ,‬כשהזיהוי מתבצע ע"י שילוב העמודות‪ Course_id :‬ו‪-‬‬
‫‪ )Student_name‬ולהוציא את עמודת ‪ Professor_id‬כמעט ולא קיימת חזרה על נתונים‪.‬‬
‫את המידע שהוסר נעדכן בטבלאות נוספות‪ ,‬אך לפני כן נבחן את שדות הנתונים שיש לאחסן (‪Course_name‬‬
‫‪ Professor_id ,‬ו ‪ )Student_id -‬ואת הקשר ביניהם‪ ,‬במקרה זה נראה‪ ,‬כי אין קשר ישיר בין השדות ועל כן‬
‫נאחסנם בטבלאות נפרדות‪( ,‬שכן למזהה הסטודנט אין קשר למזהה הפרופסור ושם הקורס מאפיין קורס ולא‬
‫ישות אדם)‪.‬‬
‫ומכאן שניצור ‪ 3‬טבלאות נוספות ‪ ,‬המכילות את השדות הנוספים ואת השדה שמייצג אותם בטבלת פרטי קורס‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪114‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫טבלת קורסים –‪:Courses‬‬

‫‪Course_id‬‬ ‫‪Course_name‬‬
‫‪10455‬‬ ‫‪Consumer‬‬
‫‪Behavior‬‬
‫‪20144‬‬ ‫‪DataBase‬‬
‫‪system‬‬

‫טבלת סטודנטים‪:Students-‬‬

‫‪Student_id‬‬ ‫‪Student_name‬‬
‫‪014‬‬ ‫‪Eyal Levin‬‬
‫‪015‬‬ ‫‪Hadas‬‬
‫‪Grossman‬‬
‫‪236‬‬ ‫‪Hilla‬‬
‫‪Zimerman‬‬
‫‪015‬‬ ‫‪Youval‬‬
‫‪Perlmoter‬‬
‫‪258‬‬ ‫‪Eran Lefler‬‬
‫‪231‬‬ ‫‪Nahama stiv‬‬

‫טבלת פרופסורים‪: Professors-‬‬

‫‪Professor_id‬‬ ‫‪Professor_name‬‬
‫‪025‬‬ ‫‪Dani Levi‬‬
‫‪036‬‬ ‫‪Liat‬‬
‫‪Barel‬‬

‫עבור כל אחת מהטבלאות נגדיר מפתח (מזהה) ראשי שהוא שדה ה‪ id-‬בכל אחת מהטבלאות‪.‬‬

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

‫ניצור את הטבלה ‪:Course_Professor‬‬

‫‪Proffesor_id‬‬ ‫‪Course_id‬‬
‫‪025‬‬ ‫‪10455‬‬
‫‪036‬‬ ‫‪20144‬‬

‫עמוד ‪115‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫וכעת הטבלה הראשונה תראה באופן הבא‪:‬‬

‫‪Course_id‬‬ ‫‪Student_id‬‬ ‫‪grade‬‬


‫‪10455‬‬ ‫‪014‬‬ ‫‪96‬‬
‫‪10455‬‬ ‫‪015‬‬ ‫‪100‬‬
‫‪20144‬‬ ‫‪236‬‬ ‫‪87‬‬
‫‪20144‬‬ ‫‪015‬‬ ‫‪76‬‬
‫‪20144‬‬ ‫‪258‬‬ ‫‪80‬‬
‫‪20144‬‬ ‫‪231‬‬ ‫‪63‬‬
‫‪20144‬‬ ‫‪015‬‬ ‫‪84‬‬

‫ציינו כבר קודם‪ ,‬כי השילוב ‪ Course_id‬ו‪ Student_id -‬מזהה רשומה‪ .‬נוודא כי בחירת כל אחת מהעמודות‬
‫בנפרד לא מהווה שילוב ייחודי אשר יזהה את הרשומה‪ .‬מאחר ובמקרה שלנו תנאי זה מתקיים אז זהו מפתח‬
‫קביל ואנו נבחרו לתפקד כמפתח ראשי עבור הטבלה‪.‬‬

‫בפתרון שהתקבל קיבלנו סה"כ ‪ 5‬טבלאות שונות אשר היוו טבלה אחת במקור‪.‬‬
‫למעשה הפתרון שהשתמשנו בו הוא הסרת הכפילויות‪ .‬חיפשנו תלויות חלקיות ‪ -‬ז"א שדות התלויים בחלק‬
‫משדות המפתח ולא במפתח כולו ויצרנו עבורם טבלאות חדשות‪.‬‬
‫בטבלאות החדשות אחסנו את השדות שהוסרו מטבלת המקור ואת השדה או קומבינצית השדות שהיוו תלות‬
‫חלקית‪.‬‬

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

‫נסכם ונחדד את השלבים בנירמול‪:‬‬


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

‫צורה נורמלית ראשונה מקיימת את הדברים הבאים‪:‬‬


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

‫צורה נורמלית שניה‪:‬‬


‫היא צורה נורמלית מספר אחת‪.‬‬
‫אין בה תלויות חלקיות (שבהן תכונה מסוימת תלויה בחלק ממפתח ראשי – לא בכולו)‬

‫הגדרה של צורה נורמלית מספר שלוש‪:‬‬


‫הטבלה היא בצורה נורמלית שניה‪.‬‬
‫אין בה תלויות טרנזיטיביות (שבהן תכונה‪ ,‬שאיננה מפתח‪ ,‬תלויה בתכונה אחרת‪ ,‬שאיננה מפתח)‪.‬‬
‫ניתן להרחיב ולהמשיך לעבור בצורות‪ ,‬אך אנו נסתפק ברמה זו‪.‬‬

‫בין הטבלאות שקיבלנו יש להגדיר קשרים‪ ,‬שכן בין הטבלאות אנו משלבים אותו מידע‪ .‬לדוגמה‪ :‬מספר מזהה‬
‫של פרופסור בטבלה המגדירה קשר בין פרופסור לקורס‪ ,‬צריך להיות כזה המופיע בטבלת הפרופסורים‪.‬‬
‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪116‬‬
‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫קשרים בין טבלאות המבוססים על שדה משותף מבטיחים כי הנתונים יהיו משותפים וכופים על המערכת קיום‬
‫של שלמות רפרנציאלית‪.‬‬

‫שלמות רפרנציאלית (שלמות של מראי מקום)‬


‫שלמות המבטיחה שערך המופיע בטבלה אחת יגרור הופעה של מספר ערכים בטבלה אחרת‪ ,‬שלמות זו‬
‫נקראת מפתח זר (‪ ) foreign key‬והיא למעשה קבוצת תכונות בטבלה אחת המהווה מפתח קביל בטבלה‬
‫האחרת‪.‬‬
‫(תזכורת‪ :‬מפתח קביל הינו אוסף של תכונות אשר אם נסיר חלק מהתכונות הוא לא יהווה יותר מפתח)‪.‬‬

‫*קישור בין טבלאות מבוצע ע"י מפתחות זרים‪.‬‬


‫ומכאן שניצור במקרה שלנו סה"כ ‪ 4‬מפתחות זרים‪:‬‬
‫‪ .1‬שדה ‪ Course_id‬בטבלת פרטי קורס יהווה מפתח זר ל ‪ Course_id -‬שבטבלת ‪. Courses‬‬
‫‪ .2‬שדה ‪ Student_id‬בטבלת פרטי קורס יהווה מפתח זר ל ‪ Student_id -‬שבטבלת ‪.Students‬‬
‫שבטבלת‬ ‫‪ .3‬שדה ‪ Professor_id‬בטבלת ‪ Course_Professor‬יהווה מפתח זר ל‪Professor_id -‬‬
‫‪Professors‬‬
‫‪ .4‬שדה ‪ Course_id‬בטבלת ‪ Course_Professor‬יהווה מפתח זר ל‪ Course_id -‬שבטבלת ‪.Courses‬‬

‫בשלב זה לאחר שהגדרנו את מבנה הטבלאות והקשרים יש לגשת להגדרת השדות‪.‬‬


‫הגדרת שדות בטבלה נקראת גם מימוש אילוצי תחום שכן עבור כל תכונה מוגדר תחום אשר בעזרתו נאכוף‬
‫את סוגי הנתונים המוכנסים לשדות‪.‬‬

‫אילוצי תחום‬
‫כל שדה יקבל סוג ‪ Data type‬ובמידת הצורך גודל בבתים‪.‬‬

‫סוגי ‪ data type‬נפוצים‪:‬‬


‫)אורך(‪Char‬‬ ‫הגדרת מחרוזת באורך קבוע ‪-‬‬
‫)אורך(‪Varchar‬‬ ‫הגדרת מחרוזת באורך לכל היותר‪-‬‬
‫‪Smallint‬‬ ‫שלם (מספר שלם)‪-‬‬
‫‪Float‬‬
‫)‪Numeric (p,d‬‬ ‫‪ p‬מספר הספרות ‪-‬‬
‫‪ d‬מספר הספרות מתוך ‪ P‬אחרי הנקודה‬
‫‪DateTime‬‬ ‫תאריך‪-‬‬
‫*פרוט מלא של סוגי הנתונים מופיעה בסוף החוברת בפרק הנספחים‪.‬‬

‫כל אחד מהשדות נוכל להגדיר כ‪ - not null -‬מה שיחייב הזנת ערך בו בהוספת רשומה ומפתח כמובן יוגדר כ‪-‬‬
‫‪.not null‬‬

‫לסיכום‪:‬‬

‫בנינו סכימה ראשית של נתונים‪.‬‬ ‫‪‬‬


‫פיצלנו את הסכימה למספר טבלאות‪.‬‬ ‫‪‬‬
‫הגדרנו מפתחות ראשיים‪.‬‬ ‫‪‬‬
‫וידאנו כי לא קיימות תלויות חלקיות ותלויות טרנזטיביות‪.‬‬ ‫‪‬‬
‫הגדרנו קשרים בין הטבלאות‪.‬‬ ‫‪‬‬
‫בחרנו ‪ Data type‬עבור כל אחד מהשדות‪.‬‬ ‫‪‬‬

‫עמוד ‪117‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫מנגנון הנעילות‬

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

‫ראשי פרקים‪:‬‬

‫‪ – Concurrency problems‬הבעיות הפונציאליות שמצריכות נעילות‬ ‫‪‬‬


‫מה ניתן לנעול‬ ‫‪‬‬
‫סוגי נעילות עיקריים‬ ‫‪‬‬
‫מדיניות נעילה‬ ‫‪‬‬
‫איך ניתן לקבל מידע על הנעילות במערכת‬ ‫‪‬‬
‫‪Optimizer hints‬‬ ‫‪‬‬
‫‪Deadlocks‬‬ ‫‪‬‬
‫‪Concurrency problems‬‬
‫‪Dirty read‬‬ ‫‪‬‬
‫טרנזקציה מסוגלת לקרוא מידע לא סופי (‪ )Uncommited‬שנוצר במסד הנתונים במהלך הביצוע של‬
‫טרנזקציה שניה‪ .‬מצב כזה עשוי להוביל להסתמכות שגויה‪.‬‬
‫‪Non Repeatable read‬‬ ‫‪‬‬
‫בטרנזקציה מתבצעות שתי גישות לאותה רשומה‪ .‬הגישה הראשונה היא ‪ .Select‬בין הגישה הראשונה‬
‫למידע לגישה השניה המידע יכול לעבור שינוי ע"י טרנזקציה אחרת‪ .‬כך שהקריאה הראשונה היא‬
‫קריאה בלתי חוזרת‪.‬‬
‫‪Phantoms‬‬ ‫‪‬‬
‫טרנזקציה מבצעת פעולה על טווח של רשומות‪ .‬במהלך ביצוע הפעולה נכנסת רשומה חדשה למסד‬
‫הנתונים השייכת לאותו הטווח‪ .‬הרשומה החדשה לא תושפע מהפעולה על הטווח‪ .‬נוצרת רשומת‬
‫רפאים שלא אמורה להתקיים ב ‪.DB -‬‬

‫כל הבעיות שהוזכרו כאן יכולות להימנע ע"י שימוש בנעילות‪.‬‬

‫מה ניתן לנעול‬

‫השרת יכול לנעול‬


‫‪ ‬שורה‬
‫‪Data page ‬‬
‫‪ ‬טבלה‬
‫‪Data base ‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪118‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫ההחלטה מה לנעול היא של השרת‬

‫השיקולים הנוגדים שהשרת לוקח בחשבון הם מצד אחד‪ ,‬מידת ההפרעה למשתמשים אחרים ב ‪( .DB -‬זו‬
‫תגדל ככל שרמת הנעילה תהיה כוללנית יותר ‪ -‬נעילה ברמת ה ‪ Data Page -‬או הטבלה)‪.‬‬
‫מצד שני השרת לוקח בחשבון את עלות משאבי הזיכרון שיאלץ להשקיע בתחזוקת הנעילות‪( .‬זו הולכת וגדלה‬
‫ככל שרמת הנעילות גרעינית יותר‪ -‬נעילה ברמת הרשומה)‪.‬‬
‫העיקרון שמנחה את ‪ SQL Server‬הוא הענקת עדיפות למינימום הפרעה למשתמשים ב ‪ Database -‬אי‬
‫לכך‪ ,‬השרת מתחיל מנעילות גרעיניות ככל האפשר אך כאשר כמות הנעילות גדלה השרת מבצע החמרה‬
‫לנעילות כוללניות יותר‪ .‬ההחמרה של הנעילות מתבצעת כאשר ‪ SQL Server‬משקיע יותר מ ‪ 40% -‬משאבי‬
‫הזיכרון שלו ניהול הנעילות כפי שמתואר בסעיף הבא‪.‬‬

‫‪Lock Escalation‬‬
‫כל נעילה תופסת לפחות ‪:96 bytes‬‬

‫המשאב הנעול‬ ‫‪‬‬


‫סוג הנעילה‬ ‫‪‬‬
‫ה ‪ Session -‬עבורו מוחזקת הנעילה‬ ‫‪‬‬

‫בנוסף השרת מקצה ‪ 32 Bytes‬עבור כל ‪ Session‬שממתין למשאב הנעול‪.‬‬


‫כאשר מספר הנעילות עבור טרנזקציה אחת עולה על ‪ ,1250‬או כאשר כמות הנעילות על טבלה אחת עולה על‬
‫‪ 765‬והשרת כבר הקצה ‪ 40%‬ממשאבי הזיכרון שלו לניהול הנעילות מתבצעת החמרה של רמת הנעילה‬
‫משורה או ‪ Data Page‬לטבלה‪.‬‬

‫‪Lock Types‬‬

‫‪Shared‬‬
‫‪ ‬השרת עושה שימוש בנעילה זו עבור פעולות ‪.select‬‬
‫‪ ‬מאפשרות קריאה של הרשומה ע"י משתמשים אחרים אך מונעות עדכון‪.‬‬

‫‪Exclusive‬‬
‫‪ ‬השרת עושה שימוש בנעילה זו עבור פעולות עדכון‪.‬‬
‫‪ ‬מונעת ממשתמשים אחרים גישה אל הרשומה‪.‬‬

‫‪Update‬‬
‫‪ ‬סוג נעילה שמהווה שלב מקדמי להפעלת נעילת ‪.Exclusive‬‬
‫מופעלת ע"י השרת בשלב של חיפוש הרשומה אותה הוא מתעתד לעדכן או למחוק‪.‬‬
‫‪ ‬מאפשרת נעילות ‪ Shaerd‬לא מאפשרת נעילות ‪ Update‬אחרות‬
‫‪ ‬מאפשרת לטפל ב ‪Conversion DeadLocks -‬‬

‫‪Intent‬‬
‫היות ונעילות יכולות להיווצר בכמה רמות גרעיניות‪ ,‬השרת זקוק למנגנון איתות שיאפשר לו לדעת האם‬ ‫‪‬‬
‫קיימת נעילה ברמת גרעיניות נמוכה במשאב אותו הוא מתעתד לנעול‪.‬‬
‫לדוגמה‪ :‬כאשר השרת רוצה ליצור נעילה ברמת הטבלה הוא צריך לדעת האם קיימות נעילות סותרות‬ ‫‪‬‬
‫ברמת ‪ Page‬או ‪ Row‬השייכים לאותה טבלה‪.‬‬

‫עמוד ‪119‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Special Lock Modes‬‬

‫‪Bulk Insert‬‬
‫‪ ‬נעילה שנוצרת עבור פעולות ‪.Bulk Insert‬‬
‫‪ ‬בפקודת ה ‪ Bulk Insert -‬יש לעשות שימוש ב – ‪.TabLock‬‬
‫‪ ‬מונעת נעילה אחרת על הטבלה להוציא ‪ Bu‬נוספת‪.‬‬

‫‪Schema stability‬‬
‫‪ ‬נוצרת בשלב הקמפול של תוכניות ביצוע בשביל למנוע שינויי מבנה באובייקטים אליהם מתייחסת‬
‫תוכנית הביצוע‪.‬‬
‫‪ ‬מונעת רכישת נעילה מסוג ‪.Schema modification‬‬

‫‪Schema Modification‬‬
‫‪ ‬נוצרת כאשר מתבצע שינוי במבנה אובייקט ב – ‪DB‬‬

‫‪SIX‬‬
‫‪Shared Intent Exclusive‬‬ ‫‪‬‬
‫לא מופעלת באופן ישיר אלא עשויה להיווצר‬ ‫‪‬‬
‫דוגמה‪ :‬על טבלה מופעלת נעילת ‪Shared‬‬ ‫‪‬‬
‫ובשלב מאוחר יותר נוצרת נעילת ‪ Exclusive‬ברמת רשומה‪.‬‬
‫על הטבלה נקבל נעילת ‪SIX‬‬

‫ההחלטה באיזה סוג נעילה להשתמש היא של השרת‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪120‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫מדיניות נעילה‬

‫‪‬‬ ‫‪Read Committed‬‬


‫‪‬‬ ‫‪Read uncommitted‬‬
‫‪‬‬ ‫‪Repeatable read‬‬
‫‪‬‬ ‫‪Serializable‬‬

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

‫‪Serializable‬‬ ‫‪Repeaable Read‬‬ ‫‪Read‬‬ ‫‪Read‬‬


‫‪unCommitted‬‬ ‫‪Committed‬‬
‫עד סוף טקנזקציה‬ ‫עד סוף טקנזקציה‬ ‫נקודתית בלבד‬ ‫עד סוף טרנזקציה‬
‫‪Exclusive‬‬

‫‪Lock‬‬
‫עד סוף טקנזקציה‬ ‫עד סוף טקנזקציה‬ ‫נקודתית בלבד‬ ‫נקודתית בלבד‬
‫‪Shared‬‬

‫‪Lock‬‬
‫‪Dirty Read‬‬ ‫‪Dirty Read‬‬ ‫‪Dirty Read‬‬
‫‪NonRepeatable‬‬ ‫‪NonRepeatable‬‬ ‫‪Concurrency‬‬
‫‪Read‬‬ ‫‪Read‬‬ ‫‪problems‬‬
‫‪Phantoms‬‬ ‫‪Prevented‬‬

‫מדיניות הנעילה נקבעת ע"י המשתמש‬


‫… ‪Set transaction isolation level‬‬

‫איך ניתן לקבל מידע על הנעילות במערכת –‬

‫שימוש ב ‪Current activity window -‬‬


‫שימוש בפקודות ‪T-sql‬‬

‫‪‬‬ ‫‪Sp_lock‬‬

‫עמוד ‪121‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Locking Optimizer Hints‬‬

‫קיימים מספר ‪ Optimizer Hints‬שמאפשרים לשלוט על היקף‪ ,‬משך וסוג הנעילה בה משתמש השרת‬
‫‪ ‬חשוב למקם את ה ‪ Hint -‬בתוך סוגריים אחרת יחשב ע"י השרת ל – ‪.Alias‬‬

‫‪Controlling Lock Granularit‬‬

‫‪ TabLock‬‬

‫כופה נעילות ‪ Shared‬ו ‪ Exclusive -‬ברמת הטבלה‪ .‬מאפשר ליצור ‪ Snap Shot‬של טבלה‪.‬‬ ‫‪‬‬
‫‪ TabLockX‬‬
‫כופה נעילות ‪ Exclusive‬ברמת הטבלה‪ .‬שווה ערך לשילוב של ‪ TabLock‬עם ‪.Xlock‬‬ ‫‪‬‬
‫‪ PagLock‬‬

‫כופה שימוש בנעילות ‪ Shared‬ו ‪ Exclusive -‬ברמת ה ‪ .Page -‬אם נרצה נעילה מסוג ‪Exclusive‬‬ ‫‪‬‬
‫עבור פעולות ‪ Select‬נוכל לשלב רמז זה עם ‪.XLock‬‬

‫‪ RowLock‬‬

‫כופה שימוש בנעילות ‪ Shared‬ו ‪ Exclusive‬ברמת הרשומה‪ .‬ניתן לשלב עם ‪.Xlock‬‬ ‫‪‬‬

‫‪Controlling Lock Type‬‬

‫‪ Updlock‬‬

‫מפעיל נעילת ‪ Update‬במקום נעילת ‪ Shared‬עבור פעולת ‪ .Select‬הנעילה מחזיקה עד סוף‬ ‫‪‬‬
‫הטרנזקציה‪ .‬שימושי במניעת ‪.Conversion DeadLocks‬‬

‫‪ Xlock‬‬

‫כופה נעילת ‪ Exclusive‬עד סוף טרנזקציה‪ .‬יכול להיות משולב עם ‪ PagLock‬או ‪.TabLock‬‬ ‫‪‬‬

‫‪Controlling Isolation Level‬‬

‫‪ READUNCOMMITTED‬‬ ‫|‬ ‫‪READCOMMITTED‬‬ ‫|‬ ‫‪REPEATABLEREAD‬‬ ‫|‬


‫‪SERIALIZABLE‬‬
‫אופציות מקבילות למדיניות הנעילה ברמת ה ‪Session -‬‬ ‫‪‬‬
‫האופציות ברמת הטבלה גוברות‬ ‫‪‬‬

‫‪ HoldLock‬‬

‫שווה ערך ל ‪ .Serializable -‬מחזיק נעילות ‪ Shared‬עד סוף טרנזקציה‪.‬‬ ‫‪‬‬

‫‪Special‬‬

‫‪ ReadPast‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪122‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫מדלג על רשומות נעולות במסגרת פעולות ‪ .Select‬רלוונטי רק עבור נעילות‬ ‫‪‬‬
‫ברמת רשומה‪ ,‬במצב נעילה ‪.Read Commited‬‬ ‫‪‬‬

‫‪DeadLocks‬‬

‫סוגים‬ ‫‪‬‬
‫טיפול‬ ‫‪‬‬
‫מניעה‬ ‫‪‬‬

‫סוגי ‪DeadLocks‬‬

‫‪Cycle DeadLock‬‬

‫‪A‬‬ ‫‪B‬‬
‫‪ B‬מנסה לרכוש נעילה על ‪ 1‬אבל‬
‫נכשל בשל הנעילה של ‪A‬‬

‫‪ A‬מחזיק ‪ Exclusive‬על ‪1‬‬

‫‪1‬‬ ‫‪2‬‬
‫‪ B‬מחזיק ‪ Exclusive‬על ‪2‬‬

‫עמוד ‪123‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Conversion DeadLock‬‬

‫‪A‬‬ ‫‪B‬‬

‫ל ‪ A -‬ו ‪ B -‬יש נעילת ‪ Shared‬על ‪1‬‬


‫‪1‬‬

‫הטיפול ב ‪DeadLocks -‬‬

‫השרת מתמודד עם ‪ DeadLocks‬ע"י הקרבה של אחת משתי הטרנזקציות והחזרה של הודעת שגיאה ‪.1205‬‬
‫איך השרת מאתר ‪DeadLocks‬‬
‫‪ ‬ה ‪ Lock Monitor -‬מחפש ‪ DeadLocks‬במערכת כל חמש שניות‪.‬‬
‫‪ ‬אם מאותר ‪ DeadLock‬השרת מקדם מונה פנימי; ‪ DeadLock Detection Counter‬ל ‪ .3 -‬המונה‬
‫יורד באחד בכל פעם שמתבצעת סריקה מבלי לאתר ‪ .DeadLock‬כאשר מונה זה גדול מ ‪ 0 -‬השרת‬
‫מחפש ‪ DeadLock‬עבור כל פעולה שמחכה למשאב נעול‪.‬‬
‫ע"י שימוש ב ‪ set DeadLock_Priority low -‬ניתן לגרום ל ‪ Proccess -‬להקריב עצמו במקרה של התנגשות‪.‬‬

‫מניעה של ‪Deadlocks‬‬

‫מניעה של ‪Cycle DeadLoacks‬‬

‫פניה למשאבים באותו הסדר‬ ‫‪‬‬

‫מניעה של ‪Conversion DeadLocks‬‬

‫שימוש ב ‪Updlock hint -‬‬ ‫‪‬‬


‫רק נעילת ‪ Update‬אחת יכולה להתקיים על משאב‬ ‫‪‬‬

‫המלצות כלליות‬

‫שמירה על טרנזקציות קצרות ככל האפשר‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪124‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫אינדקסים ‪ -‬הרחבה‬

‫תחזוקה של אינדקסים‬

‫פרגמנטציה – אינדקסים מתבלים עם הזמן ועוברים פרגמנטציה‪.‬‬

‫מאפיינים‬

‫‪ External Fragmentatio‬הסדר הלוגי והסדר הפיסי של ה ‪ Data pages -‬עליהם מאוחסן האינדקס שונה‪.‬‬
‫הסדר הפיסי של דפי המידע הוא סדר הופעתם על הדיסק‪ .‬הסדר הלוגי של הדפים הוא הסדר בו יש לקרוא‬
‫את הדפים כאשר מבצעים סריקה מסודרת של האינדקס‪.‬‬
‫‪ - Internal Fragmentation‬דפי המידע עליהם מאוחסן האינדקס אינם מלאים כדי הקיבולת שלהם‪.‬‬
‫שני המצבים המתוארים לעיל פוגמים ביעילות של השימוש באינדקס היות והפעילות של קריאת הנתונים‬
‫מהדיסק הופכת לפחות יעילה‪.‬‬

‫פרגמנטציה ‪ -‬גורמים‬
‫‪Page Splits‬‬
‫הכנסה של רשומה חדשה ל ‪ Data page -‬שבו אין מקום גורמת ל ‪.Page Split -‬‬
‫הדף מתפצל לשני דפים נפרדים שכל אחד מלא כדי ‪ .50%‬הדף החדש שנוצר‪ ,‬נוצר בסוף הפיסי של הדיסק‬
‫ובכך תורם ליצירה של ‪ External Fragmentation‬ו ‪.Internal Fragmrntation-‬‬

‫מחיקה של רשומות מהאינדקס‬


‫יוצרת חורים בדפי המידע עליהם מאוחסן האינדקס‪ .‬תורם ל ‪.Internal Fragmentation -‬‬

‫פרגמנטציה ‪ -‬אבחון‬
‫‪DBCC Showcontig‬‬

‫מבצע סריקה לוגית של האינדקס ומחזיר דו"ח‪ .‬שמאפשר לקבל מידע בנוגע לשני סוגי הפרגמנטציה‬ ‫‪‬‬
‫שהזכרנו‪.‬‬

‫מבנה‪:‬‬
‫‪DBCC SHOWCONTIG‬‬
‫} ‪[ ({'table_name'|table_id|'view_name'|view_id‬‬
‫]) ] ‪[ , 'index_name' | index_id‬‬

‫התוצאות ‪ -‬הערכים החשובים בתוצאה הם ‪:‬‬

‫‪ – Logical Scan Fragmentation‬אחוז ה ‪ Data Pages -‬שהסדר הלוגי שלהם לא תואם את הסדר‬
‫הפיסי בו הם מופיעים על הדיסק‪.‬‬

‫)‪ – Avg. Page density (full‬אחוז המילוי של ה ‪.DataPages -‬‬

‫עמוד ‪125‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫פרגמנטציה ‪ -‬סוגי טיפול‪:‬‬

‫טיפול מונע ‪ Fillfactor -‬ו ‪PadIndex -‬‬ ‫‪‬‬

‫הרציונל העומד מאחרי פרמטרים אלה הוא השארת מקום פנוי ב ‪ Data Pages -‬עליהם יושב האינדקס כך‬
‫שתהליך ה‪ Page Split -‬ידחה‪.‬‬

‫באינדקס‪.‬‬ ‫‪Leaf‬‬ ‫‪level‬‬ ‫‪ FillFactor o‬קובע את אחוז המילוי של ה ‪Pages -‬‬


‫ברירת המחדל ‪ 0 -‬שמשמעו מלא עם מקום לשורה נוספת אחת‪.‬‬

‫‪ PadIndex o‬קובע את אחוז המילוי של ה ‪ Non Leaf level Pages‬באינדקס‪.‬‬


‫‪ o‬ברירת מחדל ‪ -‬מלא עם מקום לשתי שורות נפרדות‪.‬‬

‫‪ o‬מדובר באופציות בהן ניתן לעשות שימוש במסגרת פקודת ה ‪.Create Index -‬‬

‫טיפול בדיעבד‬ ‫‪‬‬

‫‪Create index… with drop_existing o‬‬


‫• למעשה בניה מחדש של האינדקס‬
‫• השימוש ב‪ drop_existing -‬מונע בניה מחדש של ה ‪ NonClustered Indexes‬בזמן בניה‬
‫מחדש של ה ‪.Clustered -‬‬
‫• חסרון; בזמן ביצוע הפעולה האינדקס אינו זמין‬

‫‪DBCC Indexdefrag o‬‬


‫• דואג להתאמה בין הסדר הפיסי של ה ‪ data pages -‬לסדר הלוגי שלהם‪.‬‬
‫• חסרון; נותן מענה פחות טוב לפרגמנטציה‬
‫• יתרון; יכול לרוץ במקביל לפעילות השוטפת ב ‪.db -‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪126‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Index tuning wizard‬‬

‫ההחלטה על מיקום אינדקסים במסד הנתונים אינה קלה ‪ .‬כמו שכבר ראינו לאינדקסים יש יתרונות אך יש‬
‫גם חסרונות משמעותיים ;פגיעה בביצועים של פעולות ‪ DML‬כמו ‪ Insert‬ובחלק מהמקרים ‪ .Upadate‬וכן‬
‫הצורך בתחזוקה מתמדת בשל פרגמנטציה‪.‬‬
‫מה שמסבך את העניינים עוד יותר הוא הצורך ליצור אינדקסים על טבלה לא רק עבור שאילתה אחת ספציפית‪,‬‬
‫אלא כאלה שיתמכו בשלוש ארבע שאילתות עיקריות שרצות מול אותה הטבלה‪.‬‬
‫פה בא לעזרנו ה‪Index Tuning Wizard -‬‬
‫‪ ‬כלי אוטומטי שמניב המלצות למבנה אינדקסים אופטימלי ב ‪.db -‬‬
‫‪ ‬זקוק לקלט שמחזיק תיעוד של הפעילות ב ‪( db -‬הקלט מושג ע"י שימוש ב ‪.)Profiler-‬‬

‫יצירת ‪Covered Queries‬‬

‫כללי‬
‫מנגנון שמשפר ביצועים של שאילתות באופן משמעותי ע"י הפחתה של כמות ה ‪ IO -‬שהשרת נאלץ‬ ‫‪‬‬
‫לבצע‪.‬‬
‫מימוש‬
‫‪ ‬יש ליצור ‪ NonClustered Indexes‬על כל העמודות אליהן מתייחסת השאילתא‪.‬‬
‫‪ ‬המשמעות היא שהשרת מסוגל לענות על שאילתה ע"י שימוש ב‪ Leaf level pages-‬של האינדקס‬
‫מבלי שיאלץ לבצע גישה ל ‪ Data pages‬עליהם יושבת הטבלה‪.‬‬
‫דגשים‬
‫‪ ‬השרת מסוגל לשלב מספר אינדקסים בכדי לכסות שאילתה‪.‬‬
‫‪ ‬גם אינדקס מורכב שהעמודה הראשונה בו אינה רלוונטית יכול לשמש לכיסוי שאילתה‪.‬‬
‫‪ ‬גם העמודות עליהן מוגדר ה ‪ Clustered Index -‬נחשבות למכוסות‪.‬‬

‫‪Query Tuning‬‬

‫פרק זה נועד להקנות את הידע התאורטי והכישורים הטכניים הדרושים בכדי להבין את תהליך האופטימיזציה‬
‫של שאילתות ב ‪ SQL Server -‬ולעשות שימוש בכלים ש ‪ SQL Server -‬חושף לשם ניתוח תוכנית הביצוע‬
‫של שאילתה מסויימת‪ ,‬השוואה בין שתי חלופות שונות לביצוע שאילתה ועוד‪.‬‬

‫הנושאים הנידונים‪:‬‬

‫‪The Query Optimizer‬‬ ‫‪‬‬


‫‪Obtaining Execution Plan Information‬‬ ‫‪‬‬
‫‪Tips‬‬ ‫‪‬‬

‫‪The Query Optimizer‬‬

‫הרכיב ב ‪ SQL Server -‬שאחראי על בחירת תוכנית הביצוע האופטימלית עבור שאילתה נתונה‪.‬‬

‫האופטימיזציה ב ‪ SQL Server -‬היא ‪Cost Based‬‬

‫עלות נמדדת במונחים של ‪ IO‬ו ‪.CPU -‬‬ ‫‪‬‬

‫השלבים בעבודת ה ‪Optimizer -‬‬

‫עמוד ‪127‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫ניתוח השאילתא ומציאת העמודות עליהן מתבצעים חיפושים או ‪joins‬‬ ‫‪‬‬
‫בחירת אינדקסים‬ ‫‪‬‬
‫בחירת אסטרטגית ‪join‬‬ ‫‪‬‬

‫‪Obtaining Execution Plan Information‬‬

‫‪Execution Plan‬‬
‫צפייה בתוכנית הביצוע הגרפית של ה ‪ SQLSERVER MANAGEMENT STUDIO‬מאפשרת לקבל‬ ‫‪‬‬
‫‪ o‬את השלבים בביצוע השאילתא‪.‬‬
‫‪ o‬עלות ביצוע השאילתא ואפשרות השוואה בין שתי חלופות שונות לביצוע השאילתה‪.‬‬
‫‪ o‬עלות שאילתה לא מספקת את הערכים הגולמיים של כמות ‪ IO‬או זמן ‪ CPU‬שהושקעו בביצוע‬
‫הפעולה‪ ,‬אלא ערך משוקלל של שני הגורמים האלה‪( .‬יחידות עלות )‪.‬‬
‫יישום‬
‫יש לבחור בתפריט ‪. include actual execution plan  query‬‬ ‫‪‬‬
‫יש לקרוא את תוכנית הביצוע משמאל לימין‪.‬‬ ‫‪‬‬
‫כל אלמנט גרפי מייצג שלב בביצוע השאילתא‪.‬‬ ‫‪‬‬
‫סדר האלמנטים משמעותי ‪ -‬האלמנטים מסודרים לפי ציר הזמן‪.‬‬ ‫‪‬‬

‫בכדי לקבל מידע על כמות ה ‪ IO -‬וה ‪ CPU -‬שנצרכה ע"י השרת בפועל ניתן לעשות שימוש בכלים‬
‫הבאים‪:‬‬

‫‪Statistics I/O‬‬
‫מחזירה מידע על כמות ה ‪ I/O -‬שביצע השרת עבור שאילתה מסוימת‪.‬‬

‫‪Logical Reads‬‬ ‫‪‬‬


‫‪ o‬מספר ה ‪ Data pages -‬שנקראו מה ‪.Buffer Cache -‬‬
‫‪Physical Reads‬‬ ‫‪‬‬
‫‪ o‬מספר ה ‪ Data Pages -‬שנקראו מהדיסק‬
‫‪Read Ahead Reads‬‬ ‫‪‬‬
‫‪ o‬מספר ה ‪ Data Pages -‬שנקראו מהדיסק בעקבות הפעלה של מנגנון ה ‪.Read Ahead -‬‬
‫‪ o‬השרת מנסה לחזות לאיזה ‪ Data Pages‬הוא יזדקק במהלך השאילתא וקורא אותם מראש‪.‬‬
‫אין ודאות שאכן יעשה שימוש בדפים אלה‪.‬‬

‫‪Statistics Time‬‬
‫מחזירה מידע על כמות הזמן שעבר במהלך הביצוע של השאילתא‪.‬‬

‫נקבל ערכים עבור זמן ‪ CPU‬ו ‪.Elapsed Time -‬‬ ‫‪‬‬


‫התוצאות מחולקות לשלב האופטימיזציה והקמפול ולשלב הביצוע‪ .‬המידע שיעניין אותנו יופיע אחרי‬ ‫‪‬‬
‫ביצוע השאילתה‪( .‬אחרי השורה המודיעה על מספר הרשומות שהושפעו מהפעולה)‪.‬‬
‫אם נרצה לקבל רק ‪ Elapsed Time‬ניתן לעשות שימוש ב ‪ GetDate -‬לפני ואחרי ביצוע השאילתא‪.‬‬ ‫‪‬‬

‫‪TIPS‬‬
‫משפטי ‪SELECT‬‬
‫‪ ‬יש לצמצם את השימוש ב ‪ distinct -‬ו ‪.order by -‬‬
‫‪ ‬אם אין אינדקס על העמודות הרלוונטיות עשויה להיווצר טבלת עבודה לשם ביצוע המיון‬
‫‪ ‬יש להעדיף ‪ Union all‬ע"פ ‪Union‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪128‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪ o‬האחרון מחייב מיון של הרשומות‪.‬‬
‫שאילתת ‪ in‬עם רשימת ערכים קב ועים; כדאי לסדר את רשימת הערכים לפי תדירות הופעתם בטבלה‪.‬‬ ‫‪‬‬
‫ניתן לקבע טבלאות נגישות במיוחד בזיכרון ע"י שימוש ב‪ Sp_TableOption‬והאופציה ‪.PinTable‬‬ ‫‪‬‬

‫שאילתות ‪AND‬‬
‫‪ ‬מספיק להגדיר אינדקס סלקטיבי על אחד מהחיפושים‪.‬‬
‫‪ ‬השרת יעשה שימוש באינדקס ואת כל שאר החיפושים יעשה ע"י ביצוע ‪Filter‬‬

‫שאילתות ‪OR‬‬
‫‪ ‬חייבים ליצור אינדקס יעיל עבור כל אחד מתנאי החיפוש‪.‬‬
‫‪ ‬במידה ולא השרת נאלץ לבצע ‪.Table scan‬‬

‫עמוד ‪129‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪META-DATA‬‬
‫‪ SQL SERVER‬מספק מידע על האובייקטים הקיימים במערכת בשתי דרכים עיקריות‪:‬‬

‫פרוצדורות מערכת – ‪system procedures‬‬ ‫‪‬‬


‫תצוגות (‪ )VIEWS‬מערכת ‪ .system views -‬ישנן פונקציות מערכת נוספות אשר מסייעות בחיפוש המידע‬ ‫‪‬‬
‫באותם ה ‪.VIEWS‬‬

‫‪- System procedures‬‬

‫שם_אובייקט ‪ - Sp_help‬מציגה מידע בסיסי עבור כל אובייקט שהוא – מתי האובייקט נוצר‪ ,‬מי יצר את‬ ‫‪‬‬
‫האובייקט‪ ,‬מרכיבי האובייקט והגדרות נוספות‪.‬‬

‫שם_אובייקט ‪ – Sp_helptext‬מציגה את הטקס עבור אובייקטים טקסטואליים‪.‬‬ ‫‪‬‬

‫שם_טבלה ‪ – sp_columns‬מציגה את הגדרת העמודות לטבלאות‪.‬‬ ‫‪‬‬

‫שם_בסיס_נתונים ‪ – sp_helpdb‬מציגה נתונים על ה ‪ ,DB‬מתי נוצר‪ ,‬קבצים וכדומה‪.‬‬ ‫‪‬‬

‫‪- System views‬‬


‫מתצוגות אלו נשלוף את המידע על ידי שימוש במשפט ‪.SELECT‬‬

‫‪ – Sys.objects‬מציג מידע על האובייקטים במערכת‪.‬‬ ‫‪‬‬

‫‪ – Sys.views‬מציג מידע על ה ‪ VIEWS‬במערכת‪.‬‬ ‫‪‬‬

‫‪ – Sys.tables‬מציג מידע על הטבלאות במערכת‪.‬‬ ‫‪‬‬

‫‪ – Sys.columns‬מציג מידע על עמודות במערכת‪.‬‬ ‫‪‬‬

‫‪ – Sys.procedures‬מציג מידע על פרוצדורות במערכת‪.‬‬ ‫‪‬‬

‫ניתן להיעזר בפונקציות על מנת להציג מידע מסויים מתוך ה‪ ,VIEWS‬בין אם מידע על אובייקט מסויים ובין‬
‫אם מידע על ‪ DATA BASE‬מסוים‪.‬‬

‫רשימת הפונקציות‪:‬‬
‫‪( ‬מספר_אובייקט)‪ – object_name‬מקבלת מספר אובייקט ומחזירה את שמו‪.‬‬

‫(שם_אובייקט)‪ - object_id‬מקבלת שם אובייקט ומחזירה את מספרו‪.‬‬ ‫‪‬‬

‫(מספר_בסיס_נתונים)‪ - db_name‬מקבלת מספר ‪ DB‬ומחזירה את שמו‪.‬‬ ‫‪‬‬

‫(שם_בסיס_נתונים)‪ - db_id‬מקבלת שם ‪ DB‬ומחזירה את מספרו‪.‬‬ ‫‪‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪130‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪CURSOR‬‬

‫מאפשר לבצע פקודת ‪ Select‬ולעבור שורה‪ -‬שורה על התוצאה‪.‬‬


‫מבנה‪:‬‬

‫‪SQL 92 Syntax‬‬
‫[ ‪DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR FOR select_statement‬‬
‫] ] } ] ‪FOR { READ ONLY | UPDATE [ OF column_name [ ,...n‬‬
‫[;]‬

‫ארגומנטים‬

‫שם הקרסור ‪ -‬חייב להיות שם תיקני כמו שם של משתנה‪.‬‬

‫‪INSENSITIVE‬‬
‫מציין שנוצר עותק זמני של מידע הקרסור ב ‪ ,tempdb‬לפיכך‪ ,‬כול שינוי שנעשה על הטבלה לא יראה בשליפות‬
‫מהקרסור והקרסור לא יאפשר שינוי בטבלה‪.‬‬

‫‪SCROLL‬‬
‫מציין שניתן לנוע על פני הקרסור קדימה ואחורה‪ .‬אם לא מצוין אז ניתן לנוע רק קדימה (‪ .)NEXT‬לא ניתן לציין‬
‫‪ SCROLL‬כאשר יש ציון של ‪FAST_FORWARD‬‬

‫‪select_statement‬‬
‫משפט ה ‪ SELECT‬של הקרסור‪ ,‬אסור לפרט בו‪:‬‬
‫‪COMPUTE, COMPUTE BY, FOR BROWSE, INTO‬‬

‫‪READ ONLY‬‬
‫לא מאפשר עדכונים דרך הקרסור של טבלאות הבסיס‪ .‬לא ניתן להתייחס לקרסור זה במשפט ‪WHERE‬‬
‫‪ CURRENT OF‬בפקודות ‪ DELETE‬או ‪.UPDATE‬‬

‫]‪[UPDATE [OF column_name [,...n‬‬


‫מציין אילו עמודות ניתן לעדכן בקרסור‪ .‬אם אין ציון עמודות אלא רק המילה ‪ UPDATE‬אז ניתן לעדכן את כול‬
‫העמודות‪.‬‬

‫לאחר יצירת קרסור‪ ,‬ניתן להשתמש בפרוצדורות הבאות למציאת מידע‪:‬‬

‫‪sp_cursor_list‬‬
‫‪Returns a list of cursors currently visible on the connection and their attributes.‬‬

‫עמוד ‪131‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
sp_describe_cursor
Describes the attributes of a cursor, such as whether it is a forward-only or scrolling cursor.

sp_describe_cursor_columns
Describes the attributes of the columns in the cursor result set.

sp_describe_cursor_tables
Describes the base tables accessed by the cursor.

:FETCH_STATUS@@ ‫ערכי המשתנה‬

0 The FETCH statement was successful.

1- The FETCH statement failed or the row was beyond the result set.

2- The row fetched is missing.

:‫דוגמה‬
:‫קרסור חיצוני המדפיס את פרטי הספק וקרסור פנימי המדפיס את המוצרים מאותו ספק‬

DECLARE @vendor_id int, @vendor_name nvarchar(50,)


@message varchar(80), @product nvarchar(50)

PRINT '-------- Vendor Products Report'--------

DECLARE vendor_cursor CURSOR FOR


SELECT VendorID, Name
FROM Purchasing.Vendor
WHERE PreferredVendorStatus = 1
ORDER BY VendorID

OPEN vendor_cursor

FETCH NEXT FROM vendor_cursor


INTO @vendor_id, @vendor_name

WHILE @@FETCH_STATUS = 0
BEGIN
PRINT' '
SELECT @message = '----- Products From Vendor + ' :
@vendor_name

PRINT @message

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 132 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
--Declare an inner cursor based
--on vendor_id from the outer cursor.

DECLARE product_cursor CURSOR FOR


SELECT v.Name
FROM Purchasing.ProductVendor pv, Production.Product v
WHERE pv.ProductID = v.ProductID AND
pv.VendorID = @vendor_id-- Variable value from the outer cursor

OPEN product_cursor
FETCH NEXT FROM product_cursor INTO @product

IF @@FETCH_STATUS <> 0
PRINT ' <<None '>>

WHILE @@FETCH_STATUS = 0
BEGIN

SELECT @message = ' ' + @product


PRINT @message
FETCH NEXT FROM product_cursor INTO @product

END

CLOSE product_cursor
DEALLOCATE product_cursor

--Get the next vendor.


FETCH NEXT FROM vendor_cursor
INTO @vendor_id, @vendor_name
END
CLOSE vendor_cursor
DEALLOCATE vendor_cursor

133 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
‫ניהול טרנזאקציות ‪ -‬הרחבה‬

‫טרנזאקציה – יחידת עבודה לוגית היכולה להכיל מספר פקודות‪ .‬טרנזאקציה מבטיחה שכול הפקודות יבוצעו‬
‫כיחידה – או שכולן יצליחו (‪ )Commit‬או שכולן יכשלו (‪.)Rollback‬‬
‫המידע עליו עובדים נעול עד סיום טרנזאקציה ולא מאפשר למשתמשים אחרים לשנות או לקרא את המידע‪.‬‬
‫‪ ,MS‬כברירת מחדל‪ ,‬מבצע ‪ Autocommit‬או ‪ Rollback‬לכול פקודת ‪ T-SQL‬שמצליחה או נכשלת‪.‬‬

‫‪Explicit Transactions‬‬
‫לפתיחת טרנזאקציה – ]‪BEGIN TRAN[SACTION‬‬
‫לסיום טרנזאקציה – ]‪COMMIT TRAN[SACTION] / ROLLBACK TRAN[SACTION‬‬

‫‪XACT_ABORT‬‬
‫קובע האם יבוצע ‪ rollback‬אוטומטי של כול הטרנזאקציה ולא רק של הפקודה שיצרה את השגיאה כאשר‬
‫מתרחשת שגיאת זמן ריצה בטרנזאקציה‪.‬‬

‫דוגמה‪:‬‬

‫‪CREATE TABLE test‬‬


‫)‪(id int primary key‬‬

‫‪SET XACT_ABORT ON‬‬

‫‪BEGIN TRAN‬‬

‫)‪insert into test values (1‬‬


‫)‪insert into test values (2‬‬
‫יצירת שגיאה והכשלת הפקודות בטרנזאקציה ‪insert into test values (2)--‬‬
‫)‪insert into test values (3‬‬

‫‪COMMIT TRAN‬‬

‫ניהול טרנזאקציות כאשר יש טיפול בשגיאות ע"י ‪- TRY CATCH‬‬

‫‪CREATE PROCEDRE ….‬‬


‫‪AS‬‬
‫‪BEGIN TRY‬‬
‫אם הפקודה הצליחה אז היא תשמר גם אם פקודת ההכנסה השניה תכשל… ‪INSERT‬‬
‫…‪INSERT‬‬
‫‪END TRY‬‬
‫‪BGIN CATCH‬‬
‫…)(‪SELECT ERROR_NUMBER‬‬
‫‪END CATCH‬‬

‫‪CREATE PROCEDRE ….‬‬


‫‪AS‬‬
‫‪BEGIN TRY‬‬
‫‪BEGIN TRAN‬‬
‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪134‬‬
‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫רק אם הבלוק הסתיים בהצלחה אז ישמרו סופית הפקודות …‪INSERT‬‬
‫…‪INSERT‬‬
‫‪COMMIT TRAN‬‬
‫‪END TRY‬‬
‫‪BGIN CATCH‬‬
‫‪ROLLBACK TRAN‬‬
‫…)(‪SELECT ERROR_NUMBER‬‬
‫‪END CATCH‬‬

‫‪XACT_ABORT‬‬
‫כאשר מופעל בתוך ‪ TRY‬אז הופך את הטרנזאקציה ל ‪ ,uncommittable‬במקרה זה יש לבצע ‪rollback‬‬
‫מפורש‪.‬‬

‫‪XACT_STATE‬‬
‫מכיל את הערך ‪ -1‬אם הטרנזאקציה הנוכחית היא ‪uncommittable‬‬
‫מכיל את הערך ‪ 0‬אם אין טרנזאקציה פעילה‬
‫מכיל את הערך ‪ 1‬אם הטרנזאקציה הנוכחית היא ‪committable‬‬

‫‪SET XACT_ABORT ON‬‬

‫‪BEGIN TRY‬‬
‫‪BEGIN TRAN‬‬
‫‪….‬‬
‫‪COMMIT TRAN‬‬
‫‪END TRY‬‬

‫‪BEGIN CATCH‬‬
‫‪IF (XACT_STATE())=-1 --UNCOMMITABLE‬‬
‫‪ROLLBACK TRAN‬‬
‫‪ELSE IF (XACT_STATE())=1 --COMMITABLE‬‬
‫‪COMMIT TRAN‬‬
‫‪END CATCH‬‬

‫הערות‪:‬‬
‫* ‪ Try Catch‬מופעל רק בשלב ה ‪ Execute‬ולכן לא יתפוס שגיאות ‪ sysntax‬ולא יתפוס שגיאות ‪( Resolve‬כן‬
‫יתפוס למשל מחיקה של רשומות שמפירות ‪.)FK‬‬
‫* ‪ Try Catch‬לא יתפוס ‪ Fatal Errors‬שגורמות לסגירת ה ‪.Connection‬‬

‫עמוד ‪135‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫‪Implicit Transaction‬‬
‫כאשר מבקשים ‪ SET IMPLICT TRANSACTION ON‬אז כול אחת מהפקודות הבאות יכולה לפתוח‬
‫טרנזאקציה‪:‬‬
‫‪ALTER DATABASE‬‬
‫‪CREATE‬‬
‫‪DELETE‬‬
‫‪DROP‬‬
‫‪FETCH‬‬
‫‪GRANT‬‬
‫‪INSERT‬‬
‫‪OPEN‬‬
‫‪REVOKE‬‬
‫‪SELECT‬‬
‫‪TRUNCATE TABLE‬‬
‫‪UPDATE‬‬
‫לסיום הטרנזאקציה יש לבקש במפורש –‬
‫]‪COMMIT TRAN[SACTION] / ROLLBACK TRAN[SACTION‬‬
‫אם לא מסיימים את הטרנזאקציה במפורש לפני התנתקות אז השינויים לא נשמרים‪.‬‬

‫‪Nested transactions‬‬
‫ניתן לקנן טרנזאקציות מפורשות‪ ,‬בדר"כ קורה כאשר קוראים לפרוצדורה המכילה ‪BEGIN TRAN‬‬
‫ניתן לדעת מה רמתהקינון ע"י תחקור המשתנה הגלובלי ‪- @@trancount‬‬
‫ערכו ‪ 0‬אם אין טרנזאקציה פעילה‬
‫כול פתיחת טרנזאקציה מקדמת באחד‬
‫כול ‪ Commit‬מוריד אחד‬
‫פעולת ‪ Rollback‬מאפסת אותו‬

‫רק אם הטרנזאקציה החיצונית ביותר תסתיים ב ‪ Commit‬אז הכול ישמר סופית‪.‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪136‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫קימפול מחדש של פרוצדורה‬

‫כאשר מתבצעת קריאה לשאילתא‪ MS ,‬מחפש ב ‪ procedure cache‬האם יש תוכנית פעולה מוכנה לאותה‬
‫שאילתה כדי לחסוך בחישוב תוכנית פעולה מחדש‪.‬‬
‫כאשר משתמשים בפרוצדורות‪ ,‬לעיתים נרצה לקמפלן מחדש כדי לקבל תוכנית פעולה עדכנית יותר‪.‬‬

‫‪Sp_recompile‬‬
‫פרוצדורה היכולה לקבל שם טריגר או פרוצדורה אחרת ותגרום לקימפולם בקריאה הבאה להם‪ .‬ניתן לפרט‬
‫גם שם טבלה או ‪ view‬ואז כול הפרוצדרות שהשתמשו בהם יקומפלו בפעם הבאה שיקראו‪.‬‬
‫דוגמה לשימוש‪ :‬הוספת אינדקס לטבלה לא תגרום ליצירת תוכניות פעולה חדשות של השאילתות הפונות אליה‬
‫ולכן מומלץ במקרה זה להשתמש ב ‪Sp_recompile‬‬

‫'‪sp_recompile 'Orders‬‬

‫‪WITH RECOMPILE at creation‬‬


‫‪ MS‬לא ישמור תוכנית פעולה לפרוצדורה ב ‪ procedure cache‬ויבצע קימפול מחדש לפרוצדורה כול פעם‬
‫שיקראו לה‪.‬‬
‫דוגמה לשימוש‪ :‬כאשר הפרוצדורה מקבלת פרמטרים מאוד שונים זה מזה אשר היה כדאי להשתמש בתוכנית‬
‫פעולה שונה כו פעם בהתאם לערכים שהתקבלו ‪ .‬למשל‪ ,‬קבלת שני תארכים קרובים (מעט נתונים) לעומת‬
‫רחוקים (הרבה נתונים)‬

‫‪CREATE Proc SelectValueRange‬‬


‫‪@Start smallDateTime,‬‬
‫‪@End smallDateTime‬‬
‫‪with recompile‬‬
‫‪as‬‬
‫* ‪select‬‬
‫‪from Orders‬‬
‫‪where OrderDate Between @Start and @End‬‬

‫‪WITH RECOMPILE on execution‬‬


‫כאשר מעבירים חד פעמית ערכים מאוד שונים לפרוצדורה המצריכים חישוב תוכנית פעולה שונה‪.‬‬

‫‪CREATE Proc SelectValueRange‬‬


‫‪@Start smallDateTime,‬‬
‫‪@End smallDateTime‬‬
‫‪as‬‬
‫* ‪select‬‬
‫‪from Orders‬‬
‫‪where OrderDate Between @Start and @End‬‬

‫'‪exec SelectValueRange '1996-07-04','1996-07-04‬‬


‫‪exec SelectValueRange '1996-07-04','1998-05-06' with recompile‬‬

‫עמוד ‪137‬‬ ‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
‫סכמה ‪ -‬הרחבה‬

‫סכמה זהו ‪ namespace‬לאוביקטים‪ .‬שמות סכמה צריכים להיות יחודיים בתוך ‪.database‬‬
‫שם מלא לאובייקט הינו‪server.database.schema.object :‬‬
‫בתוך ‪ database‬ניתן לקצר את השם ל‪schema.object :‬‬
‫סכמת הברירת מחדל הינה ‪ dbo‬לכול המשתמשים שלא הוגדרה להם סכמת ברירת מחדל מפורשות‪.‬‬
‫כאשר משתמש פונה לאובייקט ללא ציון סכמה‪ MS ,‬מחפש קודם את האובייקט תחת הסכמת הברירת מחדל‬
‫שהוגדרה לאותו משתמש ואם לא נמצא שם האובייקט (או שלא הוגדרה סכמת ברירת מחדל לאותו משתמש)‬
‫אז ‪ MS‬מחפש תחת הסכמה של ‪dbo‬‬

‫יצירת סכמה‪:‬‬
‫‪USE NORTHWIND‬‬
‫‪GO‬‬
‫‪CREATE SCHEMA sales‬‬
‫‪GO‬‬

‫יצירת סכמת ברירת מחדל למשתמש‪:‬‬

‫‪ALTER USER user_name WTH DEFAULT_SCHEMA = sales‬‬

‫מבוא למסדי נתונים בסביבת ‪SQL Server‬‬ ‫עמוד ‪138‬‬


‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‪-‬טק מקבוצת מטריקס‬
SQL ‫תקציר פקודות‬

SELECT ‫פקודת‬
Select column, group_function(column)
From table_name
[Where condition]
[Group By group_by_expression]
[Having group_function]
[Order By column]

where ‫אופרטורים לתנאי‬


= , > ,< ,>= ,<= ,<>,!> ,!< ,!=
between....and ,not between....and
in, not in
like ,not like
is null , is not null
and ,or
not
exists , not exists
()
SET OPERATORS

SELECT <query 1>


SET OPERATOR
SELECT <query 2>
Window Functions

Function(arg1,..., argn) OVER


( [PARTITION BY <...>] [ORDER BY <....>] [<window_clause>] )

CTE

WITH <CTE name>


AS
(<CTE_definition>)
<Outer Query referencing CTE>;

139 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
DML ‫פקודות‬
insert into table_name [(column[,column….])]
values (value[,value…])

update table_name
set column=value [,column=value , ….]
[where condition]

delete [from] table_name


[where condition]

truncate table_name

MERGE tblname AS target


USING (SELECT ...) AS source ()
ON ...
WHEN MATCHED THEN
...
WHEN NOT MATCHED THEN

DDL ‫פקודות‬
create table table_name (
column data type [not null] [identity( )]
[default value] ,
……………….,
[primary key (column)]
[foreign key (column) refernces table_name(column)]
:
:
[check (condition)]
:)

drop table table_name

VIEWS

CREATE VIEW view_name


AS SUBQUERY

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 140 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
SCALAR FUNCTIONS

Mathematical Functions-

CEILING(numeric_expression)
FLOOR(numeric_expression)
ROUND(numeric_expression, length[, function])

String Functions

ASCII(character_expression)
CHAR(INTEGER_EXPRESSION)
CHARINDEX(character_expression1, character_expression2 [,start_location])
RIGHT(character_expression, integer_expression)
LEFT(character_expression, integer_expression)

LEN(character_expression)
RTRIM(character_expression)
LTRIM(character_expression)
REPLACE('character_expression1','character_expression2',
character_expres sion3')
REVERSE(character_expression)
SUBSTRING(character _expression, start, length)
LOWER(character_expression)
UPPER(character_expression)

Date and Time Functions

DATEADD(datepart, number, date)


DATEDIFF(datepart, startdate, enddate)
DATENAME(datepart, date)
DATEPART(datepart, date)
DAY(date)
GETDATE()
MONTH(date)
YEAR(date)
EOMONTH(date , Interval)
CURRENT_TIMESTAMP

141 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
CAST AND CONVERT ‫פונקציות‬

CAST(expression AS data_type)

CONVERT (data_type[(length)], expression [, style])

ISNULL ‫פונקציית‬

ISNULL(column_name, value)

case ‫משפט‬

simple case function:


case input_expression
when when_expression then result_expression
:
:
[ else else_result_expression[
end

searched case function:


case
when boolean_expression then result_expression
:
:
[else else_result_expression]
End

IIF ‫פונקציית‬

IIF(<Boolean expression> ,<value_if_TRUE>,


<value_if_FALSE_or_UNKNOWN);

SQL Server ‫מבוא למסדי נתונים בסביבת‬ 142 ‫עמוד‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬
T-SQL BASIC
‫משתנים‬

declare @local_var data_type


set @local_var=value

‫משפטי תנאי‬
if boolean_expression
begin
{sql_statement | statement_block}
end
[else
begin
{sql_statement | statement_block}]
end

while ‫לולאת‬
while bolean_expression
begin
{sql_statement | statement_block}
[break]
{sql_statement | statement_block}
[continue]
end

Stored procedure

CREATE PROCEDURE ‫שם הפרוצדורה‬


( @parameter_name1 datatype,
@parameter_name2 Datatype,……)
AS
‫קוד הפרוצדורה‬

‫קריאה לפרוצדורה‬
EXE[CUTE] ‫שם הפרוצדורה‬

ALTER PROCEDURE ‫שם הפרוצדורה‬


( @parameter_name1 datatype,
@parameter_name2 Datatype,……)
AS
‫קוד הפרוצדורה‬

DROP PROCEDURE ‫שם פרוצדורה‬

143 ‫עמוד‬ SQL Server ‫מבוא למסדי נתונים בסביבת‬


‫טק מקבוצת מטריקס‬-‫© כל הזכויות שמורות לג'ון ברייס מכללת הי‬

You might also like