מתכונת 8 במדעי המחשב - תכנות באינטרנט 899372
נבחנים אקסטרניים · שאלון 899372 · 9 שאלות · 2 שעות · פתרון מלא לכל סעיף
מבחן מתכונת במדעי המחשב, תכנות באינטרנט, במבנה של בחינת הבגרות. כל שאלה בו בנויה כמו שאלה מבגרות אחרת. לכל סעיף יש תשובה ופתרון מלא, וכל קוד מופיע ב-Java וב-C#. פתרו בזמן של הבחינה, ורק אחר כך פתחו את הפתרונות.
הוראות הבחינה
א. משך הבחינה: שעתיים.
ב. מבנה השאלון ומפתח הערכה: בשאלון זה שלושה פרקים.
פרק ראשון — (10x3) — 30 נקודות
פרק שני — (20x2)+(10x1) — 50 נקודות
פרק שלישי — (20x1) — 20 נקודות
סך הכול — 100 נקודות
ג. חומר עזר מותר בשימוש: כל חומר עזר, חוץ ממחשבון שיש בו אפשרות תכנות.
יש לכתוב במחברת הבחינה בלבד, יש לרשום "טיוטה" בראש כל עמוד המשמש טיוטה.
כתיבת טיוטה בדפים שאינם במחברת הבחינה עלולה לגרום לפסילת הבחינה.
השאלות בשאלון זה מנוסחות בלשון רבים, אף על פי כן על כל תלמידה וכל תלמיד להשיב עליהן באופן אישי.
בהצלחה!
פרק ראשון
ענו על שלוש השאלות 3-1 (לכל שאלה – 10 נקודות).
שאלה 1 · תפקיד Request.Form
בקוד הכתוב בצד השרת משתמשים לעיתים קרובות ב־Request.Form. מה תפקידו של Request.Form?
העתיקו למחברת הבחינה את התשובה הנכונה מבין האפשרויות א–ד שלפניכם.
א. שליחת קוד HTML מן השרת אל הדפדפן.
ב. קריאת הערכים שהמשתמש מילא בטופס ונשלחו לשרת בשיטת POST.
ג. העברת המשתמש מן הדף הנוכחי לדף אחר באתר.
ד. שמירת מידע המשותף לכל המשתמשים באתר.
העתיקו למחברת הבחינה את התשובה הנכונה מבין האפשרויות א–ד.
◂ פתרון מלא לשאלה 1
פתרון
ב. קריאת הערכים שהמשתמש מילא בטופס ונשלחו לשרת בשיטת POST.
מה נדרש – לזהות את תפקידו של Request.Form.
רעיון – האובייקט Request מייצג את הבקשה שהגיעה מהדפדפן אל השרת. כאשר טופס <form method="post"> נשלח, ערכי השדות שלו נשלחים בגוף הבקשה, והשרת קורא אותם לפי ה־name של כל שדה: Request.Form["name"]. האובייקט Response הוא הכיוון ההפוך – התשובה מהשרת אל הדפדפן.
פתרון – נעבור על האפשרויות:
Response.Write, לא Request.Form.<input type="text" name="fullName" />, בצד השרת כותבים:string name = Request.Form["fullName"];Response.Redirect("page.aspx").תשובה: ב.
בדיקה – "הדפדפן" שולח את השדות fullName ו־phone, והקוד בצד השרת קורא אותם ב־Request.Form["fullName"] ו־Request.Form["phone"] ומקבל בדיוק את הערכים שנשלחו; שדה שלא נשלח מחזיר null.
טעות נפוצה: לבלבל בין Request (מה שמגיע אל השרת) לבין Response (מה שהשרת שולח לדפדפן) ולבחור באפשרות א.
שאלה 2 · שאילתת SQL – דירות להשכרה בחיפה
באתר להשכרת דירות מוגדרת טבלה בשם Apartments ובה נתוני הדירות המוצעות להשכרה. בטבלה העמודות הבאות:
כתבו שאילתה בשפת SQL המחזירה את הכתובות של הדירות הנמצאות בעיר Haifa, ששכר הדירה החודשי שלהן נמוך מ־5000 ושמצבן Renovated.
כתבו שאילתה בשפת SQL המחזירה את הכתובות של הדירות הנמצאות בעיר Haifa, ששכר הדירה החודשי שלהן נמוך מ־5000 ושמצבן Renovated.
◂ פתרון מלא לשאלה 2
פתרון
SELECT address FROM Apartments WHERE city = 'Haifa' AND monthlyRent < 5000 AND aptState = 'Renovated';
מה נדרש – להחזיר עמודה אחת (address) של הדירות המקיימות שלושה תנאים יחד.
רעיון – בוחרים רק את העמודה address מהטבלה Apartments, ומסננים ב-WHERE עם שלושה תנאים המחוברים ב-AND:
city = 'Haifa' – ערך טקסט נכתב בין גרשיים בודדים.monthlyRent < 5000 – "נמוך מ־5000" פירושו קטן ממש (דירה ב־5000 בדיוק אינה נכללת); מספר נכתב בלי גרשיים.aptState = 'Renovated'.שאר העמודות (rooms, floor, hasElevator) אינן משתתפות בשאילתה.
פתרון
SELECT address
FROM Apartments
WHERE city = 'Haifa' AND monthlyRent < 5000 AND aptState = 'Renovated';בדיקה – השאילתה על טבלה קטנה לדוגמה:
| address | city | monthlyRent | aptState | נבחרה? |
|---|---|---|---|---|
| Herzl 12 | Haifa | 4200 | Renovated | כן |
| Hanassi 40 | Haifa | 4800 | Old | לא (מצב אחר) |
| Moriah 7 | Haifa | 5000 | Renovated | לא (5000 אינו נמוך מ־5000) |
| Dizengoff 90 | Tel Aviv | 4500 | Renovated | לא (עיר אחרת) |
| Hagefen 3 | Haifa | 3600 | Renovated | כן |
| Allenby 21 | Haifa | 6900 | Renovated | לא (יקרה מדי) |
התוצאה: Herzl 12, Hagefen 3.
טעות נפוצה: לכתוב monthlyRent <= 5000 (אז גם Moriah 7 תוחזר), או לכתוב את Haifa בלי גרשיים.
שאלה 3 · פלט של פונקציה בצד השרת – שורת תאים
לפניכם פונקציה בשם Func הכתובה בצד השרת. העתיקו למחברתכם את מה שיוצג בדפדפן לאחר הרצת הפונקציה Func עם הפרמטר num = 6.
public void Func(int num) {
string str = "<table border='1'><tr>";
while (num != 1) {
if (num % 2 == 0) {
str += "<td>" + num + "</td>";
num = num / 2;
}
else {
str += "<td><b>" + num + "</b></td>";
num = 3 * num + 1;
}
}
str += "<td>" + num + "</td></tr></table>";
Response.Write(str);
}העתיקו למחברתכם את מה שיוצג בדפדפן לאחר הרצת הפונקציה Func עם הפרמטר num = 6.
◂ פתרון מלא לשאלה 3
פתרון
טבלה עם מסגרת, בעלת שורה אחת ו־9 תאים: 6, 3, 10, 5, 16, 8, 4, 2, 1 (המספרים 3 ו־5 מודגשים).
(ה־HTML שנשלח: <table border='1'><tr><td>6</td><td><b>3</b></td><td>10</td><td><b>5</b></td><td>16</td><td>8</td><td>4</td><td>2</td><td>1</td></tr></table>)
מה נדרש – להבין איזה HTML הפונקציה בונה כש־num = 6, ואיך הדפדפן מציג אותו.
רעיון – הטבלה נפתחת עם <tr> אחד לפני הלולאה, וכל סיבוב מוסיף תא <td> לאותה שורה – לכן מתקבלת שורה אחת עם תאים רבים. בכל סיבוב: אם num זוגי – נוסף תא רגיל ו־num מתחלק ב־2; אם num אי־זוגי – נוסף תא שבו המספר מודגש (<b>) ו־num הופך ל־3·num+1. הלולאה נעצרת כש־num = 1, ואחריה נוסף תא אחרון עם הערך 1.
פתרון – מעקב:
| num | זוגי? | התא שנוסף | num החדש |
|---|---|---|---|
| 6 | כן | <td>6</td> | 3 |
| 3 | לא | <td><b>3</b></td> | 10 |
| 10 | כן | <td>10</td> | 5 |
| 5 | לא | <td><b>5</b></td> | 16 |
| 16 | כן | <td>16</td> | 8 |
| 8 | כן | <td>8</td> | 4 |
| 4 | כן | <td>4</td> | 2 |
| 2 | כן | <td>2</td> | 1 |
| 1 | – | הלולאה נעצרת; אחריה נוסף <td>1</td> | – |
המחרוזת שנשלחת לדפדפן:
<table border='1'><tr><td>6</td><td><b>3</b></td><td>10</td><td><b>5</b></td><td>16</td><td>8</td><td>4</td><td>2</td><td>1</td></tr></table>מה יוצג בדפדפן – טבלה עם מסגרת, שורה אחת ו־9 תאים (משמאל לימין, כי לטבלה אין dir), כשהמספרים 3 ו־5 מודגשים:
| 6 | 3 | 10 | 5 | 16 | 8 | 4 | 2 | 1 |
בדיקה – הפונקציה בדיוק כפי שהיא מופיעה בשאלה, עם num = 6, מפיקה את ה־HTML שלמעלה, ובדפדפן מוצגת שורה אחת של 9 תאים עם 3 ו־5 מודגשים. (בדיקות נוספות: עם num = 8 מתקבלים התאים 8, 4, 2, 1, ועם num = 1 – תא אחד בלבד עם 1.)
טעות נפוצה: לצייר כל מספר בשורה נפרדת – אבל <tr> נכתב פעם אחת בלבד, לפני הלולאה, ובלולאה נוספים רק תאים <td>. טעות נוספת: לשכוח את התא האחרון (1), שנוסף אחרי הלולאה.
פרק שני
ענו על שלוש שאלות: על שאלה 4 (חובה – 10 נקודות) ועל שתיים מן השאלות 7-5 (לכל שאלה – 20 נקודות).
שאלה 4 · טבלת HTML מימין לשמאל עם rowspan/colspan ותמונה (10 נקודות)
יואב, תלמיד מדעי המחשב, פיתח אתר לספריית העיר ובו טבלת שעות הפתיחה.
<!DOCTYPE html>
<html lang="he" >
<meta charset="utf-8"/>
<table style="width:300px" border=2px dir="rtl">
<tr>
<td rowspan=3>ספריית העיר</td>
<td>ראשון–חמישי</td>
<td>8:00-18:00</td>
</tr>
<tr>
<td>שישי</td>
<td>8:00-12:00</td>
</tr>
<tr>
<td colspan=2 align="center">שבת – סגור</td>
</tr>
<tr>
<td colspan=2>טלפון</td>
<td>04-8123456</td>
</tr>
</table>
</html>כיצד יוצג הדף? כתבו במחברת הבחינה את מספר התשובה הנכונה מבין האפשרויות (a-d).

כתבו שורת קוד מתאימה ב- html כך שבתא שבו כתוב "ספריית העיר" תוצג, מתחת לכיתוב, התמונה books.png ברוחב 60 פיקסלים.
◂ פתרון מלא לשאלה 4
סעיף א
a
מה נדרש: לזהות איך הדפדפן מסדר את תאי הטבלה.
רעיון: עוברים שורה-שורה ומניחים כל תא במקום הפנוי הבא. dir="rtl" – הטבלה נבנית מימין לשמאל: התא הראשון בכל שורה מוצג מימין. rowspan=3 – התא תופס את המקום שלו גם בשתי השורות הבאות; colspan=2 – התא תופס שתי עמודות.
פתרון – בניית הטבלה (3 עמודות, נספור מימין):
| שורה | מה כתוב בקוד | התוצאה |
|---|---|---|
| 1 | ספריית העיר עם rowspan=3, ראשון–חמישי, 8:00-18:00 | ספריית העיר בעמודה הימנית (תופס גם את שורות 2–3), ראשון–חמישי באמצע, 8:00-18:00 משמאל |
| 2 | שישי, 8:00-12:00 | העמודה הימנית תפוסה, ולכן שישי באמצע ו-8:00-12:00 משמאל |
| 3 | שבת – סגור עם colspan=2, ממורכז | העמודה הימנית עדיין תפוסה, ולכן התא תופס את שתי העמודות השמאליות |
| 4 | טלפון עם colspan=2, 04-8123456 | טלפון תופס את שתי העמודות הימניות, המספר בעמודה השמאלית |
מתקבלת הטבלה של אפשרות a.
בדיקה: הצגנו את הקוד בדפדפן וקיבלנו בדיוק את הסידור של a. האפשרויות האחרות נפסלות:
dir="ltr".טעות נפוצה: לסדר את התאים משמאל לימין מתוך הרגל, למרות dir="rtl".
סעיף ב
<td rowspan=3>ספריית העיר<br><img src="books.png" width="60"></td>
מה נדרש: להוסיף תמונה בתוך התא הקיים, מתחת לטקסט.
רעיון: תמונה מוסיפים בתגית <img> (תגית בודדת, בלי תגית סוגרת): src – שם קובץ התמונה, width – הרוחב בפיקסלים. כדי שהתמונה תופיע מתחת לכיתוב ולא לצידו, שמים לפניה ירידת שורה <br>. הכול בתוך אותו <td>, שנשאר עם rowspan=3.
פתרון: מחליפים את שורת התא הראשון בשורה:
<td rowspan=3>ספריית העיר<br><img src="books.png" width="60"></td>בדיקה: בדקנו שסידור התאים בטבלה עם השורה החדשה זהה לקודם (התא עדיין תופס שלוש שורות בעמודה הימנית); בתא מוצג הכיתוב ספריית העיר ומתחתיו התמונה ברוחב 60 פיקסלים.
טעות נפוצה: לכתוב <img href=...> במקום src, או לשים את התמונה בתא חדש – תא נוסף משבש את מבנה הטבלה.
שאלה 5 · Session – הפניית נהג באתר חניה עירוני
באתר החניה של עירייה, נהג מזמין מקום חניה ברחוב. כדי לקבוע לאיזה דף יעבור הנהג, האתר משתמש במשתני Session הבאים:
בהתבסס על משתנים אלה, האתר מפנה את הנהג לדף המתאים:
כתבו בצד שרת קוד המתאים לדרישות.
כתבו בצד שרת קוד המתאים לדרישות.
◂ פתרון מלא לשאלה 5
פתרון
if (isResident && (hour < 8 || hour >= 18)) Response.Redirect("freeParking.aspx");
else if (vehicle == "electric" || (vehicle == "motorcycle" && hour >= 10 && hour < 16)) Response.Redirect("reducedRate.aspx");
else Response.Redirect("payParking.aspx");
מה נדרש – קוד C# בצד השרת שקורא שלושה משתני Session (מספר, בוליאני ומחרוזת) ומפנה לאחד משלושה דפים.
רעיון
int.Parse(Session["hour"].ToString()), bool.Parse(Session["isResident"].ToString()), ואת סוג הרכב קוראים כמחרוזת: Session["vehicle"].ToString().isResident && (hour < 8 || hour >= 18). הסוגריים חובה.vehicle == "electric" || (vehicle == "motorcycle" && hour >= 10 && hour < 16). "החל מ־10 (כולל)" ⇐ >=, "לפני 16" ⇐ <.פתרון (בתוך Page_Load של הדף):
protected void Page_Load(object sender, EventArgs e)
{
int hour = int.Parse(Session["hour"].ToString());
bool isResident = bool.Parse(Session["isResident"].ToString());
string vehicle = Session["vehicle"].ToString();
if (isResident && (hour < 8 || hour >= 18))
Response.Redirect("freeParking.aspx");
else if (vehicle == "electric" || (vehicle == "motorcycle" && hour >= 10 && hour < 16))
Response.Redirect("reducedRate.aspx");
else
Response.Redirect("payParking.aspx");
}בדיקה:
| hour | isResident | vehicle | דף |
|---|---|---|---|
| 21 | true | private | freeParking.aspx |
| 7 | true | electric | freeParking.aspx (הכלל הראשון קודם) |
| 18 | true | motorcycle | freeParking.aspx (18 כלול) |
| 12 | true | electric | reducedRate.aspx (תושב, אבל בשעות היום) |
| 22 | false | electric | reducedRate.aspx (חשמלי – בכל שעה) |
| 10 | false | motorcycle | reducedRate.aspx (10 כלול) |
| 16 | false | motorcycle | payParking.aspx (16 אינו "לפני 16") |
| 9 | true | private | payParking.aspx |
| 23 | false | private | payParking.aspx |
בכל השעות 0–23 עם תושב/לא תושב ושלושת סוגי הרכב המשתמש מופנה לדף הנכון.
טעות נפוצה: להשוות מחרוזת ב-Session ישירות בלי ToString (Session["vehicle"] == "electric" משווה הפניות של object ולא את תוכן המחרוזות, ועלול להחזיר false גם כשהערך הוא electric), ולשכוח סוגריים סביב החלק של האופנוע או סביב hour < 8 || hour >= 18.
protected void Page_Load(object sender, EventArgs e)
{
int hour = int.Parse(Session["hour"].ToString());
bool isResident = bool.Parse(Session["isResident"].ToString());
string vehicle = Session["vehicle"].ToString();
if (isResident && (hour < 8 || hour >= 18))
Response.Redirect("freeParking.aspx");
else if (vehicle == "electric" || (vehicle == "motorcycle" && hour >= 10 && hour < 16))
Response.Redirect("reducedRate.aspx");
else
Response.Redirect("payParking.aspx");
}שאלה 6 · מספר מאוזן – ספרות זוגיות ואי-זוגיות
נגדיר מספר מאוזן – מספר שלם חיובי שבו מספר הספרות הזוגיות שווה למספר הספרות האי-זוגיות (הספרה 0 נחשבת ספרה זוגית).
דוגמאות למספרים מאוזנים: 1234, 50, 207813
דוגמאות למספרים שאינם מאוזנים: 135, 2468, 7, 12345
כתבו פונקציה בשם isBalanced בצד שרת המקבלת מספר שלם חיובי ומחזירה אמת אם המספר מאוזן. אחרת, מחזירה שקר.
כתבו פונקציה בשם isBalanced בצד שרת המקבלת מספר שלם חיובי ומחזירה אמת אם המספר מאוזן. אחרת, מחזירה שקר.
◂ פתרון מלא לשאלה 6
פתרון
public bool isBalanced(int num) – מפרקים את המספר לספרות (% 10, / 10), סופרים ספרות זוגיות (d % 2 == 0) ואי-זוגיות, ומחזירים evenCount == oddCount.
מה נדרש: פונקציה ב-C# (צד שרת) שמחזירה true אם במספר יש בדיוק אותו מספר של ספרות זוגיות ושל ספרות אי-זוגיות.
רעיון: מפרקים את המספר לספרות: num % 10 היא הספרה האחרונה, ו-num / 10 מסיר אותה. לכל ספרה בודקים אם היא זוגית (d % 2 == 0, כולל 0) ומקדמים את המונה המתאים. בסוף משווים בין שני המונים.
פתרון – הקוד המלא בלשונית C#:
public bool isBalanced(int num)
{
int evenCount = 0;
int oddCount = 0;
while (num > 0)
{
int d = num % 10;
if (d % 2 == 0)
evenCount++;
else
oddCount++;
num = num / 10;
}
return evenCount == oddCount;
}בדיקה – מעקב על 207813:
| num | d | זוגית? | evenCount | oddCount |
|---|---|---|---|---|
| 207813 | 3 | לא | 0 | 1 |
| 20781 | 1 | לא | 0 | 2 |
| 2078 | 8 | כן | 1 | 2 |
| 207 | 7 | לא | 1 | 3 |
| 20 | 0 | כן | 2 | 3 |
| 2 | 2 | כן | 3 | 3 |
בסוף 3 = 3 ⇐ true.
על הדוגמאות שבשאלה: 1234, 50, 207813 ⇐ True; 135, 2468, 7, 12345 ⇐ False.
טעות נפוצה: לבדוק את זוגיות המספר (num % 2) במקום את זוגיות הספרה (d % 2); או לעצור את הלולאה כשהספרה היא 0 (למשל while (num % 10 != 0)) – אז במספר כמו 50 הספרה 0 לא תיספר.
public bool isBalanced(int num)
{
int evenCount = 0;
int oddCount = 0;
while (num > 0)
{
int d = num % 10;
if (d % 2 == 0)
evenCount++;
else
oddCount++;
num = num / 10;
}
return evenCount == oddCount;
}שאלה 7 · שאילתות SQL על טבלת מוצרי מזנון
במסד הנתונים של מזנון בית הספר יש טבלה ששמה Products המכילה את נתוני המוצרים הנמכרים במזנון.
העמודות בטבלה הן:
א. pname (שם המוצר), מסוג טקסט.
ב. category (קטגוריה), מסוג טקסט.
ג. price (מחיר המוצר בשקלים), מסוג מספר שלם.
ד. stock (מספר היחידות במלאי), מסוג מספר שלם.
דוגמה לטבלה ובה מוצרי המזנון:
| stock | price | category | pname |
|---|---|---|---|
| 40 | 5 | משקאות | מים מינרליים |
| 25 | 7 | משקאות | שוקו |
| 10 | 12 | משקאות | מיץ תפוזים |
| 30 | 6 | חטיפים | ביסלי |
| 8 | 15 | מאפים | כריך טונה |
| 0 | 9 | מאפים | בורקס |
יש לבחור 2 מתוך 4 הסעיפים הבאים:
כתבו שאילתה בשפת SQL המציגה את שמות המוצרים ואת מחיריהם, עבור המשקאות שמחירם קטן מ-10 ש״ח.
כתבו שאילתה בשפת SQL המחזירה את השווי הכולל של המלאי במזנון (לכל מוצר: מחיר × מספר יחידות במלאי, ואז סכום על כל המוצרים). בדוגמה: יוחזר 795
כתבו שאילתה בשפת SQL המעלה ב-2 ש״ח את המחיר של כל המוצרים בקטגוריה מאפים.
כתבו שאילתה בשפת SQL המחזירה את המחיר הגבוה ביותר של מוצר במזנון. בדוגמה: יוחזר 15
◂ פתרון מלא לשאלה 7
סעיף 1
SELECT pname, price FROM Products WHERE category = 'משקאות' AND price < 10
מה נדרש: להציג שתי עמודות (pname, price) לשורות שמקיימות שני תנאים: הקטגוריה היא משקאות וגם המחיר קטן מ-10.
רעיון: מחברים את שני התנאים ב-WHERE בעזרת AND. ערך הטקסט 'משקאות' נכתב בגרשיים, והמספר 10 – בלי גרשיים.
פתרון:
SELECT pname, price FROM Products WHERE category = 'משקאות' AND price < 10בדיקה: על טבלת הדוגמה התקבלו 2 שורות: מים מינרליים 5, שוקו 7. מיץ תפוזים (12) לא הוצג, וגם ביסלי (6, אבל חטיפים) לא הוצג.
טעות נפוצה: לכתוב OR במקום AND – אז יוצגו כל המשקאות וגם כל המוצרים הזולים מכל הקטגוריות.
סעיף 2
SELECT SUM(price * stock) FROM Products (בדוגמה: 795)
מה נדרש: מספר אחד – סכום של price * stock על כל השורות.
רעיון: בתוך פונקציית הצבירה SUM אפשר לכתוב ביטוי חשבוני על עמודות. לכל שורה מחושב price × stock, ו-SUM מחבר את התוצאות.
פתרון:
SELECT SUM(price * stock) FROM Productsבדיקה: על טבלת הדוגמה: 5·40 + 7·25 + 12·10 + 6·30 + 15·8 + 9·0 = 200 + 175 + 120 + 180 + 120 + 0 = 795.
טעות נפוצה: לכתוב SUM(price) * SUM(stock) – זו מכפלה של שני סכומים (54 · 113) ולא סכום של מכפלות.
סעיף 3
UPDATE Products SET price = price + 2 WHERE category = 'מאפים'
מה נדרש: לשנות ערך בעמודה price בשורות קיימות – רק בשורות של מאפים.
רעיון: פקודת UPDATE ... SET משנה ערכים בשורות קיימות. SET price = price + 2 מחשב את הערך החדש מהערך הישן של אותה שורה, ו-WHERE קובע אילו שורות משתנות.
פתרון:
UPDATE Products SET price = price + 2 WHERE category = 'מאפים'בדיקה: על טבלת הדוגמה עודכנו 2 שורות: כריך טונה 15 ⇐ 17, בורקס 9 ⇐ 11. שאר המוצרים לא השתנו.
טעות נפוצה: לכתוב SET price = 2 – זה קובע מחיר 2 במקום להעלות ב-2. או לשכוח את ה-WHERE, ואז כל המוצרים מתייקרים.
סעיף 4
SELECT MAX(price) FROM Products (בדוגמה: 15)
מה נדרש: מספר אחד – הערך הגדול ביותר בעמודה price.
רעיון: פונקציית הצבירה MAX מחזירה את הערך הגדול ביותר בעמודה (על כל השורות, כי אין WHERE).
פתרון:
SELECT MAX(price) FROM Productsבדיקה: על טבלת הדוגמה התקבל 15 (כריך טונה).
טעות נפוצה: לכתוב SELECT price FROM Products WHERE price = MAX(price) – אי אפשר להשתמש בפונקציית צבירה בתוך WHERE.
פרק שלישי
ענו על שאלה אחת מן השאלות 9-8.
שאלה 8 · תכנון טבלת הזמנות – חדרי בריחה
חברת חדרי הבריחה "המנעול" רוצה לשמור את ההזמנות שלה בטבלה Bookings במסד הנתונים. לכל הזמנה נשמרים הפרטים הבאים:
שתי הזמנות שיש להוסיף:
תכננו את הטבלה Bookings: לכל עמודה רשמו את שמה, את טיפוס הנתונים שלה והאם מותר להשאיר בה ערך ריק, וציינו מהו המפתח הראשי. לאחר מכן כתבו פקודות SQL המוסיפות לטבלה את שתי ההזמנות שלמעלה.
תכננו את הטבלה Bookings: לכל עמודה רשמו את שמה, את טיפוס הנתונים שלה והאם מותר להשאיר בה ערך ריק, וציינו מהו המפתח הראשי. לאחר מכן כתבו פקודות SQL המוסיפות לטבלה את שתי ההזמנות שלמעלה.
◂ פתרון מלא לשאלה 8
פתרון
BookingId int IDENTITY – מפתח ראשי; TeamName nvarchar(25) NOT NULL; Phone nvarchar(10) NOT NULL; Room nvarchar(10) NOT NULL; Players int NOT NULL; BookingDate date NOT NULL; Paid bit NOT NULL; Notes nvarchar(100) NULL.
INSERT INTO Bookings (TeamName, Phone, Room, Players, BookingDate, Paid, Notes)
VALUES ('המפצחים', '0521234567', 'צוללת', 4, '2027-03-14', 1, NULL);
INSERT INTO Bookings (TeamName, Phone, Room, Players, BookingDate, Paid, Notes)
VALUES ('הבלשים הצעירים', '0549876543', 'פירמידה', 6, '2027-03-21', 0, 'יום הולדת');
מה נדרש – לתכנן טבלה מתוך תיאור במילים (שם, טיפוס, חובה/רשות, מפתח ראשי) ולכתוב INSERT לשתי הזמנות נתונות.
רעיון – לכל פרט בתיאור בוחרים את הטיפוס המתאים: מספר שלם – int, טקסט – nvarchar באורך המקסימלי, תאריך – date, כן/לא – bit. "חובה" פירושו שאסור ערך ריק (NOT NULL). המפתח הראשי הוא השדה שמזהה כל הזמנה – מספר ההזמנה, ומכיוון שהוא נוצר אוטומטית מגדירים אותו IDENTITY ולא כותבים אותו ב-INSERT.
פתרון
מבנה הטבלה:
| שם העמודה | טיפוס נתונים | מותר ערך ריק | הערה |
|---|---|---|---|
| BookingId | int (IDENTITY) | לא | מפתח ראשי, נוצר אוטומטית |
| TeamName | nvarchar(25) | לא | |
| Phone | nvarchar(10) | לא | טקסט ולא מספר – כדי לא לאבד את ה-0 שבהתחלה |
| Room | nvarchar(10) | לא | 'מעבדה' / 'פירמידה' / 'צוללת' |
| Players | int | לא | 2 עד 6 |
| BookingDate | date | לא | |
| Paid | bit | לא | 1 – שולם, 0 – לא שולם |
| Notes | nvarchar(100) | כן |
אותו מבנה כפקודת SQL:
CREATE TABLE Bookings (
BookingId INT IDENTITY(1,1) PRIMARY KEY,
TeamName NVARCHAR(25) NOT NULL,
Phone NVARCHAR(10) NOT NULL,
Room NVARCHAR(10) NOT NULL,
Players INT NOT NULL,
BookingDate DATE NOT NULL,
Paid BIT NOT NULL,
Notes NVARCHAR(100) NULL
);הוספת שתי ההזמנות (בלי BookingId – הוא נוצר לבד):
INSERT INTO Bookings (TeamName, Phone, Room, Players, BookingDate, Paid, Notes)
VALUES ('המפצחים', '0521234567', 'צוללת', 4, '2027-03-14', 1, NULL);
INSERT INTO Bookings (TeamName, Phone, Room, Players, BookingDate, Paid, Notes)
VALUES ('הבלשים הצעירים', '0549876543', 'פירמידה', 6, '2027-03-21', 0, 'יום הולדת');התאריך נכתב בתבנית 'yyyy-mm-dd' (ב-Access כותבים #2027-03-14#), "שולמה" הוא 1 ו"לא שולמה" הוא 0, וכשאין הערה כותבים NULL.
בדיקה – כשהכללים כתובים כאילוצים (IDENTITY, CHECK), שתי הפקודות: התקבלו הרשומות (1, 'המפצחים', '0521234567', 'צוללת', 4, '2027-03-14', 1, NULL) ו-(2, 'הבלשים הצעירים', '0549876543', 'פירמידה', 6, '2027-03-21', 0, 'יום הולדת'). הזמנה עם 7 משתתפים או עם 1, חדר 'מרתף' או בלי שם קבוצה – נדחתה. ועוד בדקנו: אם Phone מוגדר כמספר, הערך 0521234567 נשמר כ-521234567 – ה-0 אובד.
טעות נפוצה: להגדיר את הטלפון כ-int; לכתוב ב-INSERT ערך ל-BookingId שהוא IDENTITY; ולכתוב את המספרים 4 ו-6 בין גרשיים או את שם הקבוצה בלי גרשיים.
שאלה 9 · חיפוש תחנות אופניים – Request.QueryString
לפניכם התוכנית הבאה בדף Search.aspx (אין טעויות תחביר). בטבלה Stations שמורות תחנות השכרת אופניים: העיר (City) ומספר האופניים הפנויים בתחנה (FreeBikes).
01. <%@ Page Language="C#" %>
02. <%@ Import Namespace="System.Data" %>
03. <%@ Import Namespace="System.Data.SqlClient" %>
04.
05. <script runat="server">
06. public string msg = "";
07. protected void Page_Load(object sender, EventArgs e)
08. {
09. if (Session["user"] == null)
10. Response.Redirect("Login.aspx");
11.
12. string city = Request.QueryString["city"];
13. if (city != null && city != "")
14. {
15. SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\bikes.mdf;Integrated Security=True");
16. SqlCommand command = new SqlCommand("", connection);
17. command.CommandText = string.Format("Select * From Stations Where City = '{0}' And FreeBikes > 0", city);
18. SqlDataAdapter adapter = new SqlDataAdapter(command);
19. DataTable dt = new DataTable();
20. adapter.Fill(dt);
21. msg = "נמצאו " + dt.Rows.Count + " תחנות עם אופניים פנויים";
22. }
23. }
24. </script>
25. <html xmlns="http://www.w3.org/1999/xhtml">
26. <head runat="server">
27. <title>Bikes</title>
28. </head>
29. <body>
30. <form id="form1" action="Search.aspx" method="get">
31. <input type="text" name="city" />
32. <input type="submit" value="Search" />
33. </form>
34. <p><%= msg %></p>
35. </body>
36. </html>לפניכם חמישה הגדים, רשמו עבור כל הגד נכון / לא נכון.
לפניכם חמישה הגדים, רשמו עבור כל הגד נכון / לא נכון.
◂ פתרון מלא לשאלה 9
פתרון
1 – נכון; 2 – לא נכון; 3 – נכון; 4 – לא נכון; 5 – לא נכון
מה נדרש – לקבוע לכל אחד מחמשת ההגדים אם הוא נכון.
רעיון – לעקוב מה Page_Load עושה בכל בקשה, ולשים לב לשורה 30: הטופס נשלח בשיטה get, ולכן הנתונים עוברים בכתובת (Query String) ונקראים ב-Request.QueryString.
פתרון
מה הקוד עושה: בכל בקשה לדף, אם המשתמש לא מחובר (שורה 9) – מעבר ל-Login.aspx, ו-Response.Redirect מסיים את הטיפול בבקשה. אחרת נקראת העיר מהכתובת (שורה 12); רק אם היא קיימת ואינה ריקה (שורה 13) נשלחת שאילתה שמחזירה את התחנות באותה עיר שיש בהן אופניים פנויים (שורה 17), ונבנית ההודעה עם מספר השורות שהתקבלו (שורה 21), שמוצגת בשורה 34.
| הגד | תשובה | הסבר |
|---|---|---|
| 1 | נכון | בטופס עם method="get" הדפדפן מוסיף את שדות הטופס לכתובת: Search.aspx?city=.... |
| 2 | לא נכון | שורות 9–10: כש-Session["user"] הוא null יש מעבר ל-Login.aspx, והטיפול בבקשה מסתיים – השאילתה לא מתבצעת. |
| 3 | נכון | בלי פרמטרים Request.QueryString["city"] הוא null, התנאי בשורה 13 לא מתקיים, והשורות 15–21 לא מתבצעות (ההודעה ריקה). |
| 4 | לא נכון | בשאילתה יש And FreeBikes > 0, ולכן התחנה בלי אופניים פנויים לא נספרת: יוצג "נמצאו 2 תחנות עם אופניים פנויים". |
| 5 | לא נכון | הטופס עדיין נשלח ב-get, כך שהעיר נמצאת בכתובת ולא בגוף הבקשה. Request.Form["city"] יהיה null, השאילתה לא תתבצע ולא תוצג הודעה. צריך לשנות גם את הטופס ל-method="post". |
בדיקה – קוד השרת (שורות 6–23) עם הטבלה (בחיפה 3 תחנות, באחת 0 אופניים פנויים):
| בקשה | תוצאה |
|---|---|
| משתמש מחובר, Search.aspx?city=חיפה | "נמצאו 2 תחנות עם אופניים פנויים" |
| משתמש לא מחובר, Search.aspx?city=חיפה | מעבר ל-Login.aspx |
| משתמש מחובר, Search.aspx בלי פרמטרים | אין שאילתה, הודעה ריקה |
| אחרי החלפה ל-Request.Form, הטופס ב-get עם city=חיפה | אין שאילתה, הודעה ריקה |
טעות נפוצה: לענות על הגד 4 "נכון" בלי לקרוא את תנאי השאילתה עד הסוף, ולחשוב ש-Request.Form ו-Request.QueryString מחליפים זה את זה – כל אחד מתאים לשיטת שליחה אחרת (post / get).
טבלת התשובות
| שאלה | סעיף | תשובה |
|---|---|---|
| 1 | - | ב. קריאת הערכים שהמשתמש מילא בטופס ונשלחו לשרת בשיטת POST. |
| 2 | - | SELECT address FROM Apartments WHERE city = 'Haifa' AND monthlyRent < 5000 AND aptState = 'Renovated'; |
| 3 | - | טבלה עם מסגרת, בעלת שורה אחת ו־9 תאים: 6, 3, 10, 5, 16, 8, 4, 2, 1 (המספרים 3 ו־5 מודגשים). |
| 4 | א | a |
| ב | <td rowspan=3>ספריית העיר<br><img src="books.png" width="60"></td> | |
| 5 | - | if (isResident && (hour < 8 || hour >= 18)) Response.Redirect("freeParking.aspx"); |
| 6 | - |
|
| 7 | 1 |
|
| 2 |
| |
| 3 |
| |
| 4 |
| |
| 8 | - | BookingId int IDENTITY – מפתח ראשי; TeamName nvarchar(25) NOT NULL; Phone nvarchar(10) NOT NULL; Room nvarchar(10) NOT NULL; Players int NOT NULL; BookingDate date NOT NULL; Paid bit NOT NULL; Notes nvarchar(100) NULL. |
| 9 | - | 1 – נכון; 2 – לא נכון; 3 – נכון; 4 – לא נכון; 5 – לא נכון |