מתכונת 2 במדעי המחשב - תכנות באינטרנט 899372
נבחנים אקסטרניים · שאלון 899372 · 9 שאלות · 2 שעות · פתרון מלא לכל סעיף
מבחן מתכונת במדעי המחשב, תכנות באינטרנט, במבנה של בחינת הבגרות. כל שאלה בו בנויה כמו שאלה מבגרות אחרת. לכל סעיף יש תשובה ופתרון מלא, וכל קוד מופיע ב-Java וב-C#. פתרו בזמן של הבחינה, ורק אחר כך פתחו את הפתרונות.
הוראות הבחינה
א. משך הבחינה: שעתיים.
ב. מבנה השאלון ומפתח הערכה: בשאלון זה שלושה פרקים.
פרק ראשון — (10x3) — 30 נקודות
פרק שני — (20x2)+(10x1) — 50 נקודות
פרק שלישי — (20x1) — 20 נקודות
סך הכול — 100 נקודות
ג. חומר עזר מותר בשימוש: כל חומר עזר, חוץ ממחשבון שיש בו אפשרות תכנות.
יש לכתוב במחברת הבחינה בלבד, יש לרשום "טיוטה" בראש כל עמוד המשמש טיוטה.
כתיבת טיוטה בדפים שאינם במחברת הבחינה עלולה לגרום לפסילת הבחינה.
השאלות בשאלון זה מנוסחות בלשון רבים, אף על פי כן על כל תלמידה וכל תלמיד להשיב עליהן באופן אישי.
בהצלחה!
פרק ראשון
ענו על שלוש השאלות 3-1 (לכל שאלה – 10 נקודות).
שאלה 1 · ההבדל בין קוד בצד השרת לקוד בצד הלקוח
מה ההבדל בין קוד הכתוב בצד השרת (למשל ב-C#) ובין קוד הכתוב בצד הלקוח (למשל ב-JavaScript)?
(1) קוד בצד השרת רץ בדפדפן של המשתמש, לעומת קוד בצד הלקוח שרץ במחשב השרת. בנוסף, רק קוד בצד הלקוח יכול לגשת לבסיס הנתונים של האתר.
(2) קוד בצד השרת רץ במחשב השרת, לעומת קוד בצד הלקוח שרץ בדפדפן של המשתמש. בנוסף, קוד בצד הלקוח יכול לגשת ישירות לבסיס הנתונים שבשרת.
(3) קוד בצד השרת רץ במחשב השרת ושולח לדפדפן את התוצאה, לעומת קוד בצד הלקוח שנשלח לדפדפן ורץ בו. בנוסף, המשתמש אינו יכול לראות את קוד צד השרת, אך יכול לראות את קוד צד הלקוח.
(4) קוד בצד השרת נשלח לדפדפן ורץ בו, לעומת קוד בצד הלקוח שרץ במחשב השרת. בנוסף, המשתמש יכול לראות את קוד צד השרת, אך אינו יכול לראות את קוד צד הלקוח.
מה ההבדל בין קוד הכתוב בצד השרת (למשל ב-C#) ובין קוד הכתוב בצד הלקוח (למשל ב-JavaScript)?
◂ פתרון מלא לשאלה 1
פתרון
(3)
מה נדרש – לבחור את התשובה הנכונה על ההבדל בין קוד שרץ בצד השרת (C# ב-ASP.NET) ובין קוד שרץ בצד הלקוח (JavaScript).
רעיון – לשאול על כל קוד: איפה הוא רץ ומה מגיע לדפדפן.
פתרון
| תשובה | נכון/לא נכון | למה |
|---|---|---|
| (1) | ✘ | הפוך: קוד צד השרת רץ בשרת, וקוד צד הלקוח רץ בדפדפן. גם הגישה לבסיס הנתונים היא דרך קוד צד השרת. |
| (2) | ✘ | החלק הראשון נכון, אבל קוד בצד הלקוח אינו ניגש ישירות לבסיס הנתונים שבשרת. |
| (3) | ✔ נכון | השרת מריץ את הקוד ושולח רק את התוצאה; JavaScript נשלח לדפדפן ורץ בו, ולכן אפשר לראות אותו. |
| (4) | ✘ | הפוך בשני החלקים. |
התשובה: (3).
בדיקה – קוד שרת שמחשב בלולאה 1+2+...+10 וכותב <p>55</p>, ואחריו <script>document.write(2 + 3);</script>. מה שהגיע לדפדפן היה <p>55</p><script>document.write(2 + 3);</script>: ממה שכתוב ב-C# הגיעה רק התוצאה 55, ואילו קוד ה-JavaScript הגיע כמו שהוא, והדפדפן הוא שהריץ אותו והציג 5.
טעות נפוצה: לחשוב שמה שכתוב בדף ה-aspx נשלח כמו שהוא לדפדפן. הדפדפן מקבל רק HTML (ו-JavaScript), לא את קוד ה-C#.
שאלה 2 · שאילתת SQL – מלאי בחנות אופניים
במסד הנתונים של חנות מקוונת לחלקי אופניים מוגדרת טבלה בשם Parts ובה נתוני המוצרים בחנות. בטבלה יש שש עמודות:
א. קוד מוצר (code).
ב. שם המוצר (pname).
ג. שם הספק (supplier).
ד. מחיר (price).
ה. כמות במלאי (stock).
ו. כמות מינימלית שחייבת להיות במלאי (minStock).
כתבו שאילתה בשפת SQL המאחזרת את שמות המוצרים ואת שמות הספקים של המוצרים שהכמות שלהם במלאי קטנה או שווה לכמות המינימלית.
◂ פתרון מלא לשאלה 2
פתרון
SELECT pname, supplier FROM Parts WHERE stock <= minStock;
מה נדרש – שאילתה שמחזירה שתי עמודות (שם המוצר ושם הספק) רק עבור השורות שבהן stock ≤ minStock.
רעיון – בוחרים (SELECT) את העמודות pname ו־supplier, מהטבלה (FROM) Parts, ומסננים שורות בתנאי (WHERE) שמשווה בין שתי עמודות באותה שורה: stock <= minStock.
פתרון
SELECT pname, supplier
FROM Parts
WHERE stock <= minStock;בדיקה – השאילתה על טבלה קטנה לדוגמה:
| code | pname | supplier | price | stock | minStock |
|---|---|---|---|---|---|
| 101 | פנימית 26 | אופני צפון | 25 | 40 | 15 |
| 102 | שרשרת | גלגל-טק | 60 | 8 | 10 |
| 103 | רפידות בלם | אופני צפון | 35 | 12 | 12 |
| 104 | אוכף | רכיבה פלוס | 120 | 5 | 3 |
| 105 | פנס קדמי | גלגל-טק | 80 | 0 | 4 |
התוצאה:
| pname | supplier |
|---|---|
| שרשרת | גלגל-טק |
| רפידות בלם | אופני צפון |
| פנס קדמי | גלגל-טק |
רפידות הבלם הוחזרו כי 12 = 12 (שוויון נכלל); הפנימית והאוכף לא הוחזרו כי אצלם stock > minStock.
טעות נפוצה: לכתוב < במקום <= – אז מוצר שהכמות שלו שווה בדיוק לכמות המינימלית לא יוחזר. טעות נוספת: להשוות לערך קבוע (למשל stock <= 10) במקום לעמודה minStock של אותה שורה.
שאלה 3 · Response.Write של טבלת מדרגות
לפניכם הפונקציה Stairs(), רשמו מה יוצג על הדפדפן לאחר הרצת הפונקציה
public void Stairs()
{
string str = "<table border = '1'>";
for (int i = 1; i <= 4; i++)
{
str += "<tr>";
for (int j = 1; j <= 6; j++)
{
if (j <= i)
str += "<td>*</td>";
else
str += "<td>" + (j - i) + "</td>";
}
str += "</tr>";
}
str += "</table>";
Response.Write(str);
}לפניכם הפונקציה Stairs(), רשמו מה יוצג על הדפדפן לאחר הרצת הפונקציה.
◂ פתרון מלא לשאלה 3
פתרון
טבלה עם מסגרת, 4 שורות ו-6 עמודות: בשורה i יש i כוכביות ואחריהן המספרים 1, 2, ... עד 6−i.
מה נדרש – לכתוב מה הדפדפן מציג אחרי ש-Stairs() בונה מחרוזת HTML ושולחת אותה ב-Response.Write.
רעיון – הלולאה החיצונית (i מ-1 עד 4) בונה שורות <tr>, והפנימית (j מ-1 עד 6) בונה בכל שורה 6 תאים <td>. בתא שבו j ≤ i נכתב *, ובשאר התאים נכתב j − i. לכן בשורה i יש קודם i כוכביות, ואחריהן המספרים 1, 2, 3, ... (כי j − i גדל ב-1 בכל תא).
פתרון – מעקב לשורה הראשונה והאחרונה:
| i | j = 1 | j = 2 | j = 3 | j = 4 | j = 5 | j = 6 |
|---|---|---|---|---|---|---|
| 1 | * (1 ≤ 1) | 2−1 = 1 | 2 | 3 | 4 | 5 |
| 4 | * | * | * | * | 5−4 = 1 | 6−4 = 2 |
המחרוזת שנשלחת לדפדפן:
<table border = '1'><tr><td>*</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr><tr><td>*</td><td>*</td><td>1</td><td>2</td><td>3</td><td>4</td></tr><tr><td>*</td><td>*</td><td>*</td><td>1</td><td>2</td><td>3</td></tr><tr><td>*</td><td>*</td><td>*</td><td>*</td><td>1</td><td>2</td></tr></table>מה יוצג בדפדפן – טבלה עם מסגרת (border = '1'), 4 שורות ו-6 עמודות (בטבלה אין שורת כותרת – השורה הראשונה היא שורה רגילה):
| * | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| * | * | 1 | 2 | 3 | 4 |
| * | * | * | 1 | 2 | 3 |
| * | * | * | * | 1 | 2 |
בדיקה – מתקבלת בדיוק המחרוזת שלמעלה: 4 תגיות <tr> ו-24 תאים, השורה הראשונה * 1 2 3 4 5 והאחרונה * * * * 1 2.
טעות נפוצה: לכתוב בתא את j במקום j − i (למשל * 2 3 4 5 6 בשורה הראשונה), או להעתיק את תגיות ה-HTML כ"פלט" – הדפדפן מפרש את התגיות ומציג טבלה.
פרק שני
ענו על שלוש שאלות: על שאלה 4 (חובה – 10 נקודות) ועל שתיים מן השאלות 7-5 (לכל שאלה – 20 נקודות).
שאלה 4 · טבלת HTML עם rowspan/colspan וקישור לחלון חדש (10 נקודות)
נועה, תלמידת מדעי המחשב, בנתה אתר לבית קפה שכונתי ובו תפריט.
<!DOCTYPE html>
<html lang="he" >
<meta charset="utf-8"/>
<table style="width:220px" border=2px dir="ltr">
<tr>
<td colspan=3 align="center">Menu</td>
</tr>
<tr>
<td rowspan=2>Drinks</td>
<td>Latte</td>
<td>14</td>
</tr>
<tr>
<td>Tea</td>
<td>9</td>
</tr>
<tr>
<td rowspan=2>Cakes</td>
<td>Cheesecake</td>
<td rowspan=2>18</td>
</tr>
<tr>
<td>Brownie</td>
</tr>
<tr>
<td colspan=2 align="center">Open</td>
<td>8-22</td>
</tr>
</table>
</html>כיצד יוצג הדף? כתבו במחברת הבחינה את מספר התשובה הנכונה מבין האפשרויות (a-d).

כתבו שורת קוד מתאימה ב- html כך שלחיצה על המילה Menu תפתח את הדף menu.html בחלון (לשונית) חדש של הדפדפן.
◂ פתרון מלא לשאלה 4
סעיף א
c
מה נדרש: לזהות איך הדפדפן מסדר את תאי הטבלה.
רעיון: עוברים שורה-שורה (<tr>) ומניחים כל תא (<td>) במקום הפנוי הבא בשורה. colspan=3 – התא תופס שלוש עמודות; rowspan=2 – התא תופס גם את המקום שלו בשורה הבאה, ולכן בשורה הבאה יש פחות תאים בקוד. dir="ltr" – התא הראשון בכל שורה מוצג משמאל.
פתרון – בניית הטבלה (3 עמודות):
| שורה | מה כתוב בקוד | התוצאה |
|---|---|---|
| 1 | Menu עם colspan=3, ממורכז | Menu על פני שלוש העמודות |
| 2 | Drinks עם rowspan=2, Latte, 14 | Drinks בעמודה השמאלית (תופס גם את שורה 3), Latte באמצע, 14 מימין |
| 3 | Tea, 9 | העמודה השמאלית תפוסה ע"י Drinks, ולכן Tea באמצע ו-9 מימין |
| 4 | Cakes עם rowspan=2, Cheesecake, 18 עם rowspan=2 | Cakes משמאל ו-18 מימין – שניהם תופסים גם את שורה 5 |
| 5 | רק Brownie | העמודה השמאלית והימנית תפוסות, ולכן Brownie נכנס לעמודה האמצעית, מתחת ל-Cheesecake |
| 6 | Open עם colspan=2, ממורכז, 8-22 | Open על פני שתי העמודות השמאליות, 8-22 מימין |
מתקבלת הטבלה של אפשרות c.
בדיקה: הצגנו את הקוד בדפדפן וקיבלנו בדיוק את סידור התאים של c. האפשרויות האחרות נפסלות:
dir="rtl".טעות נפוצה: לשכוח שתא עם rowspan "גונב" מקום בשורה הבאה גם כשהוא בעמודה הימנית – לכן ל-Brownie נשאר רק המקום האמצעי.
סעיף ב
<td colspan=3 align="center"><a href="menu.html" target="_blank">Menu</a></td>
מה נדרש: להפוך את המילה Menu לקישור לדף menu.html שנפתח בחלון חדש.
רעיון: קישור נכתב בתגית <a>: התכונה href מכילה את כתובת היעד (כאן דף באותו אתר, לכן מספיק שם הקובץ), והתכונה target="_blank" גורמת לדפדפן לפתוח את היעד בחלון/לשונית חדשים. עוטפים את המילה Menu בתוך התא הקיים, כך שהתא נשאר עם colspan=3 ו-align="center".
פתרון: מחליפים את שורת התא הראשון בשורה:
<td colspan=3 align="center"><a href="menu.html" target="_blank">Menu</a></td>בדיקה: בדקנו שהטבלה עם השורה החדשה מסודרת בדיוק כמו קודם (אותו סידור תאים), והמילה Menu מוצגת כקישור במרכז השורה העליונה. לחיצה עליה פותחת את menu.html בלשונית חדשה, והתפריט המקורי נשאר פתוח.
טעות נפוצה: לכתוב target="blank" בלי קו תחתון, או לשים את <a> מחוץ ל-<td> – זה HTML לא תקין.
שאלה 5 · הפניית מבקר לפי משתני Session
באתר להזמנת כרטיסים לגן החיות העירוני הוגדרו שלושה משתני Session:
כתבו קטע המפנה את המבקר באתר לדף המתאים לו, על פי הוראות אלו:
א. מבקר מתחת לגיל 3, או מבקר מגיל 67 ומעלה, יועבר לעמוד free.aspx
ב. מבקר אחר שהוא תושב העיר ומבקר ביום שישי (fri) או בשבת (sat) יועבר לעמוד resident.aspx
ג. שאר המבקרים יועברו לעמוד tickets.aspx
◂ פתרון מלא לשאלה 5
פתרון
if (age < 3 || age >= 67) Response.Redirect("free.aspx");
else if (resident && (day == "fri" || day == "sat")) Response.Redirect("resident.aspx");
else Response.Redirect("tickets.aspx");
מה נדרש – קטע קוד C# בצד השרת שקורא שלושה משתני Session ומפנה את המבקר לאחד משלושה דפים.
רעיון
(int)Session["age"], (string)Session["day"], (bool)Session["resident"] – כל ערך ב־Session הוא object.age < 3; "מגיל 67 ומעלה" ⇒ age >= 67; אחד מהשניים מספיק ⇒ ||.resident) וגם יום שישי או שבת. לכן: resident && (day == "fri" || day == "sat") – הסוגריים חובה.פתרון
int age = (int)Session["age"];
string day = (string)Session["day"];
bool resident = (bool)Session["resident"];
if (age < 3 || age >= 67)
{
Response.Redirect("free.aspx");
}
else if (resident && (day == "fri" || day == "sat"))
{
Response.Redirect("resident.aspx");
}
else
{
Response.Redirect("tickets.aspx");
}בדיקה:
| age | day | resident | הדף שהתקבל |
|---|---|---|---|
| 2 | sat | true | free.aspx |
| 67 | fri | true | free.aspx |
| 80 | tue | false | free.aspx |
| 3 | sat | true | resident.aspx |
| 66 | fri | true | resident.aspx |
| 30 | sat | false | tickets.aspx |
| 30 | mon | true | tickets.aspx |
| 10 | wed | false | tickets.aspx |
גבולות: בן 3 כבר אינו "מתחת לגיל 3", ובן 67 כבר נכנס לכלל א.
טעות נפוצה: לכתוב resident && day == "fri" || day == "sat" בלי סוגריים. האופרטור && קודם ל־||, ולכן הביטוי מתפרש כ־(resident && day == "fri") || day == "sat" – ומבקר שאינו תושב שמגיע בשבת יועבר בטעות ל־resident.aspx (במקרה 30, sat, false בטבלה הוא צריך להגיע ל־tickets.aspx). טעות נוספת: להשוות Session["resident"] == true בלי המרה ל־bool.
int age = (int)Session["age"];
string day = (string)Session["day"];
bool resident = (bool)Session["resident"];
if (age < 3 || age >= 67)
{
Response.Redirect("free.aspx");
}
else if (resident && (day == "fri" || day == "sat"))
{
Response.Redirect("resident.aspx");
}
else
{
Response.Redirect("tickets.aspx");
}שאלה 6 · פעולת שרת IsHarmony – סכום ומכפלת ספרות
נגדיר מספר Harmony – מספר שלם חיובי בן שתי ספרות לפחות, שסכום הספרות שלו שווה למכפלת הספרות שלו.
דוגמאות למספרים Harmony:
דוגמאות למספרים שאינם Harmony:
כתבו בצד שרת פעולה בשם IsHarmony המקבלת מספר שלם חיובי – num, ומחזירה אמת אם המספר הוא Harmony. אחרת, מחזירה שקר.
כתבו בצד שרת פעולה בשם IsHarmony המקבלת מספר שלם חיובי – num, ומחזירה אמת אם המספר הוא Harmony. אחרת, מחזירה שקר.
◂ פתרון מלא לשאלה 6
פתרון
אם num < 10 מחזירים false; אחרת מחשבים בלולאה את סכום הספרות ואת מכפלת הספרות (product מאותחל ל־1) ומחזירים sum == product.
מה נדרש – פעולה בוליאנית ב-C# בצד השרת, שבודקת שני תנאים: המספר בן שתי ספרות לפחות, וסכום ספרותיו שווה למכפלת ספרותיו.
רעיון
num < 10 מחזירים מיד false.n % 10 היא ספרת האחדות, ו-n / 10 (חילוק שלמים) מוחק אותה. בכל סיבוב מוסיפים את הספרה לסכום ומכפילים אותה במכפלה.sum == product.פתרון
public bool IsHarmony(int num)
{
if (num < 10)
return false;
int sum = 0;
int product = 1;
int n = num;
while (n > 0)
{
int digit = n % 10;
sum += digit;
product *= digit;
n = n / 10;
}
return sum == product;
}בדיקה:
| num | סכום | מכפלה | תוצאה |
|---|---|---|---|
| 22 | 4 | 4 | true |
| 123 | 6 | 6 | true |
| 1124 | 8 | 8 | true |
| 25 | 7 | 10 | false |
| 7 | – | – | false (ספרה אחת) |
| 1000 | 1 | 0 | false |
| 11 | 2 | 1 | false |
המספרים Harmony עד 2000: 22, 123, 132, 213, 231, 312, 321, 1124, 1142, 1214, 1241, 1412, 1421.
טעות נפוצה: לאתחל את המכפלה ל־0 (ואז היא תמיד 0), או לשכוח את התנאי של שתי ספרות לפחות – ואז כל מספר חד-ספרתי יוחזר בטעות כ-Harmony.
public bool IsHarmony(int num)
{
if (num < 10)
return false;
int sum = 0;
int product = 1;
int n = num;
while (n > 0)
{
int digit = n % 10;
sum += digit;
product *= digit;
n = n / 10;
}
return sum == product;
}שאלה 7 · שאילתות SQL על טבלת שייט (20 נקודות)
במסד הנתונים של חברת שייט בנמל יש טבלה ששמה BoatTours המכילה את נתוני ההפלגות של היום. העמודות בטבלה הן:
דוגמה לטבלה:
| tourName | places | price | adults | kids |
|---|---|---|---|---|
| "שייט שקיעה" | 60 | 120 | 38 | 10 |
| "צפייה בדולפינים" | 40 | 95 | 22 | 18 |
| "דיג בים" | 12 | 150 | 9 | 0 |
| "סירת זכוכית" | 30 | 70 | 14 | 16 |
| "הפלגה לאי" | 80 | 180 | 51 | 7 |
יש לבחור 2 מתוך 4 הסעיפים הבאים:
כתבו שאילתה בשפת SQL שמחזירה את כמות ההפלגות שמחיר הכרטיס בהן קטן מ-100 ש"ח. דוגמה: בטבלה הנוכחית יוחזר הערך 2 (עבור צפייה בדולפינים וסירת זכוכית).
כתבו שאילתה בשפת SQL המחזירה את מחיר הכרטיס הזול ביותר מבין כל ההפלגות. דוגמה: בטבלה הנוכחית יוחזר הערך 70 ("סירת זכוכית").
כתבו שאילתה בשפת SQL שמחזירה את שמות ההפלגות ואת מספר המקומות בסירה, בהפלגות שבהן נמכרו כל המקומות (מספר כרטיסי המבוגר ועוד מספר כרטיסי הילד שווה למספר המקומות בסירה).
כתבו שאילתה בשפת SQL שמחזירה את סך כל הכרטיסים (מבוגר וילד) שנמכרו בכל ההפלגות. דוגמה: בטבלה הנוכחית יוחזר הערך 185 (48+40+9+30+58).
◂ פתרון מלא לשאלה 7
סעיף א
SELECT COUNT(*) AS cheapTours FROM BoatTours WHERE price < 100;
מה נדרש: מספר ההפלגות (כמה שורות) שבהן price קטן מ-100.
רעיון: מסננים ב-WHERE את השורות עם price < 100, וסופרים אותן בפונקציית הצבירה COUNT(*).
פתרון:
SELECT COUNT(*) AS cheapTours
FROM BoatTours
WHERE price < 100;בדיקה: על טבלת הדוגמה: המחירים הקטנים מ-100 הם 95 (צפייה בדולפינים) ו-70 (סירת זכוכית). התקבל 2, כמו בדוגמה.
טעות נפוצה: להחזיר את שמות ההפלגות במקום את הכמות, או לכתוב <= 100 במקום < 100.
סעיף ב
SELECT MIN(price) AS lowestPrice FROM BoatTours;
מה נדרש: הערך הקטן ביותר בעמודה price.
רעיון: פונקציית הצבירה MIN מחזירה את הערך הקטן ביותר בעמודה. אין צורך ב-WHERE – בודקים את כל ההפלגות.
פתרון:
SELECT MIN(price) AS lowestPrice
FROM BoatTours;בדיקה: המחירים הם 120, 95, 150, 70, 180. התקבל 70, כמו בדוגמה.
טעות נפוצה: לכתוב SELECT price FROM BoatTours WHERE price = MIN(price) – אי אפשר להשתמש בפונקציית צבירה בתוך WHERE.
סעיף ג
SELECT tourName, places FROM BoatTours WHERE adults + kids = places;
מה נדרש: שם ומספר מקומות של כל הפלגה שבה adults + kids = places.
רעיון: בוחרים את העמודות tourName ו-places, ובתנאי WHERE משווים ביטוי חשבוני של שתי עמודות (adults + kids) לעמודה שלישית באותה שורה – SQL מאפשר לחשב ולהשוות בין עמודות, לא רק מול קבוע.
פתרון:
SELECT tourName, places
FROM BoatTours
WHERE adults + kids = places;בדיקה: על טבלת הדוגמה:
| tourName | places |
|---|---|
| צפייה בדולפינים | 40 |
| סירת זכוכית | 30 |
(22 + 18 = 40 ו-14 + 16 = 30; בשאר ההפלגות: 48 < 60, 9 < 12, 58 < 80.)
סעיף ד
SELECT SUM(adults + kids) AS totalSold FROM BoatTours;
מה נדרש: סכום כל הכרטיסים – מבוגר וילד – בכל השורות.
רעיון: פונקציית הצבירה SUM יכולה לחבר ביטוי: בכל שורה מחושב adults + kids, ו-SUM מחבר את התוצאות של כל השורות. (גם SUM(adults) + SUM(kids) נכון.)
פתרון:
SELECT SUM(adults + kids) AS totalSold
FROM BoatTours;בדיקה: 48 + 40 + 9 + 30 + 58 = 185 – התוצאה 185, כמו בדוגמה.
טעות נפוצה: להשתמש ב-COUNT – זה סופר שורות (5) ולא מחבר ערכים; או לחבר רק את adults.
פרק שלישי
ענו על שאלה אחת מן השאלות 9-8.
שאלה 8 · ASP.NET ומסד נתונים – כניסה לחדר בריחה (השלמת קוד)
בטופס הכניסה באתר של חדר בריחה נדרש המשתמש להזין את קוד ההזמנה שלו ואת מספר המשתתפים שהגיעו בפועל:
<input type="text" name="bookingCode" id="bookingCode"/>
<input type="text" name="players" id="players"/>במסד הנתונים של האתר קיימת טבלה בשם bookings ובה שתי עמודות:
bookingCode (טקסט), קוד ההזמנה (ייחודי)
players (מספר שלם), מספר המשתתפים שעבורם בוצעה ההזמנה
דוגמה לתוכן הטבלה:
| bookingCode | players |
|---|---|
| E100 | 4 |
| E200 | 6 |
לפניכם קטע קוד חלקי של פעולה בשם CheckBooking שמטרתה לבדוק את הנתונים שהוזנו על ידי המשתמש. בהתאם לתוצאות הבדיקה, יש להפנות את המשתמש לעמוד מתאים לפי הכללים הבאים:
הניחו כי המשתמש מזין בשדה players מספר שלם חיובי.
עליכם להשלים את הקוד החסר.
protected void CheckBooking(string connectionString)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand();
DataSet ds = new DataSet();
command.CommandText = string.Format(
"SELECT * FROM bookings WHERE bookingCode = '{0}'",
Request.Form["bookingCode"]);
command.Connection = connection;
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(ds);
connection.Close();
// *************** השלימו כאן ***************
}עליכם להשלים את הקוד החסר.
◂ פתרון מלא לשאלה 8
פתרון
if (ds.Tables[0].Rows.Count == 0) Response.Redirect("noBooking.aspx");
else if (int.Parse(Request.Form["players"]) > int.Parse(ds.Tables[0].Rows[0]["players"].ToString())) Response.Redirect("tooMany.aspx");
else Response.Redirect("startGame.aspx");
מה נדרש – להשלים את סוף הפעולה: לפי תוצאת השאילתה שכבר נמצאת ב-ds, להפנות לאחד משלושת העמודים.
רעיון
adapter.Fill(ds) התוצאה נמצאת בטבלה ds.Tables[0].ds.Tables[0].Rows.Count הוא 0 – הקוד לא קיים ⇐ noBooking.aspx.ds.Tables[0].Rows[0]. משווים מספרים: את מה שהוזן בטופס (Request.Form["players"] – מחרוזת) ממירים ב-int.Parse, ואת הערך מהעמודה players (מטיפוס object) ממירים ב-int.Parse(... .ToString()).פתרון – הקוד להשלמה (במקום ההערה "השלימו כאן"):
if (ds.Tables[0].Rows.Count == 0)
Response.Redirect("noBooking.aspx");
else if (int.Parse(Request.Form["players"]) > int.Parse(ds.Tables[0].Rows[0]["players"].ToString()))
Response.Redirect("tooMany.aspx");
else
Response.Redirect("startGame.aspx");בדיקה – ההשלמה עם DataSet שמולא בתוצאת השאילתה, על טבלת הדוגמה בתוספת הזמנה E300 ל־2 משתתפים:
| bookingCode | players שהוזן | players בהזמנה | דף |
|---|---|---|---|
| E100 | 3 | 4 | startGame.aspx |
| E100 | 4 | 4 | startGame.aspx (שוויון מותר) |
| E100 | 5 | 4 | tooMany.aspx |
| E200 | 6 | 6 | startGame.aspx |
| E200 | 10 | 6 | tooMany.aspx |
| E300 | 3 | 2 | tooMany.aspx |
| E999 | 2 | – | noBooking.aspx |
השאילתה עצמה: עבור 'E100' מוחזרת השורה E100 | 4, ועבור 'E999' – אין שורות.
טעות נפוצה: להשוות את הערכים כמחרוזות (למשל "10" > "6" אינו חוקי ב-C#, ו-CompareTo על מחרוזות ישווה לפי סדר מילוני, שבו "10" קטן מ-"6"). טעות נוספת: לגשת ל-Rows[0] לפני שבודקים שיש שורות – כשהקוד לא קיים זו שגיאת ריצה.
if (ds.Tables[0].Rows.Count == 0)
Response.Redirect("noBooking.aspx");
else if (int.Parse(Request.Form["players"]) > int.Parse(ds.Tables[0].Rows[0]["players"].ToString()))
Response.Redirect("tooMany.aspx");
else
Response.Redirect("startGame.aspx");שאלה 9 · השלמת פעולה המציגה טבלת מכוניות
במסד הנתונים של מגרש מכוניות משומשות יש טבלה בשם Cars ובה ארבע עמודות: model (דגם, טקסט), year (שנת ייצור, מספר שלם), km (מספר הקילומטרים שהמכונית נסעה, מספר שלם), price (מחיר בשקלים, מספר שלם).
דוגמה לטבלה:
| price | km | year | model |
|---|---|---|---|
| 72000 | 85000 | 2019 | טויוטה קורולה |
| 31000 | 140000 | 2016 | יונדאי i10 |
| 58000 | 42000 | 2021 | קיה פיקנטו |
| 39000 | 100000 | 2015 | מאזדה 3 |
| 81000 | 99999 | 2020 | סקודה אוקטביה |
מנהל המגרש מעוניין להציג ללקוחות טבלה של המכוניות שנסעו פחות מ-100000 ק״מ. בטבלה יוצגו רק הדגם, שנת הייצור והמחיר של כל מכונית (בסדר זה), ללא מספר הקילומטרים.
הפונקציה showCars מקבלת מחרוזת התחברות למסד הנתונים – connectionString – ומציגה את הטבלה המתאימה.
בפונקציה חסרים חמישה ביטויים המסומנים במספרים בין סוגריים עגולים. כתבו במחברת הבחינה את מספרי הביטויים החסרים (1) – (5), בסדר עולה, וכתבו ליד כל מספר את הביטוי החסר שהוא מייצג.
protected void showCars(string connectionString)
{
string str = "";
DataSet ds = _____(1)_____;
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "select * from Cars where _____(2)_____";
cmd.Connection = connection;
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(_____(3)_____);
connection.Close();
str += "<table dir=rtl><tr><th>דגם</th><th>שנה</th><th>מחיר</th></tr>";
foreach (DataRow row in ds.Tables[0].Rows)
{
_____(4)_____
}
str += "</table>";
_____(5)_____
}כתבו במחברת הבחינה את מספרי הביטויים החסרים (1) – (5), בסדר עולה, וכתבו ליד כל מספר את הביטוי החסר שהוא מייצג.
◂ פתרון מלא לשאלה 9
פתרון
new DataSet()km < 100000dsstr += "<tr><td>" + row["model"] + "</td><td>" + row["year"] + "</td><td>" + row["price"] + "</td></tr>";Response.Write(str);מה נדרש: להשלים חמישה ביטויים בפונקציה ששולפת את המכוניות שנסעו פחות מ-100000 ק״מ ומציגה מהן שלוש עמודות בלבד.
רעיון – מעבר על הפונקציה לפי הסדר:
ds מוצהר מטיפוס DataSet, ובהמשך ממלאים אותו – לכן צריך ליצור אובייקט חדש ⇐ new DataSet().km < 100000.Fill ממלא את ה-DataSet בתוצאות השאילתה ⇐ ds.str += "<tr><td>" + row["model"] + "</td><td>" + row["year"] + "</td><td>" + row["price"] + "</td></tr>";str מוכנה צריך לשלוח אותה לדפדפן ⇐ Response.Write(str);. בלי השורה הזאת הטבלה נבנית אך לא מוצגת.פתרון – תשובה במחברת:
new DataSet()km < 100000dsstr += "<tr><td>" + row["model"] + "</td><td>" + row["year"] + "</td><td>" + row["price"] + "</td></tr>";Response.Write(str);הפונקציה המלאה – בלשונית C#.
בדיקה:
select * from Cars where km < 100000, על טבלת הדוגמה מחזירה 3 מכוניות – טויוטה קורולה, קיה פיקנטו, סקודה אוקטביה (99999 < 100000). מאזדה 3 (100000 בדיוק) ויונדאי i10 (140000) לא הוחזרו.<tr><td>קיה פיקנטו</td><td>2021</td><td>58000</td></tr>, ומספרי הקילומטרים לא מופיעים בה.טעות נפוצה: בסעיף (4) להוסיף גם את row["km"] (התאים לא יתאימו לכותרות), או לכתוב את העמודות בסדר אחר מהכותרות. בסעיף (5) לכתוב Response.Write(html) – שם המשתנה כאן הוא str.
protected void showCars(string connectionString)
{
string str = "";
DataSet ds = new DataSet();
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "select * from Cars where km < 100000";
cmd.Connection = connection;
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(ds);
connection.Close();
str += "<table dir=rtl><tr><th>דגם</th><th>שנה</th><th>מחיר</th></tr>";
foreach (DataRow row in ds.Tables[0].Rows)
{
str += "<tr><td>" + row["model"] + "</td><td>" + row["year"] + "</td><td>" + row["price"] + "</td></tr>";
}
str += "</table>";
Response.Write(str);
}טבלת התשובות
| שאלה | סעיף | תשובה |
|---|---|---|
| 1 | - | (3) |
| 2 | - | SELECT pname, supplier FROM Parts WHERE stock <= minStock; |
| 3 | - | טבלה עם מסגרת, 4 שורות ו-6 עמודות: בשורה i יש i כוכביות ואחריהן המספרים 1, 2, ... עד 6−i. •1 2 3 4 5 / * * 1 2 3 4 / * * * 1 2 3 / * * * * 1 2 |
| 4 | א | c |
| ב | <td colspan=3 align="center"><a href="menu.html" target="_blank">Menu</a></td> | |
| 5 | - | if (age < 3 || age >= 67) Response.Redirect("free.aspx"); |
| 6 | - | אם num < 10 מחזירים false; אחרת מחשבים בלולאה את סכום הספרות ואת מכפלת הספרות (product מאותחל ל־1) ומחזירים sum == product. |
| 7 | א | SELECT COUNT(*) AS cheapTours FROM BoatTours WHERE price < 100; |
| ב | SELECT MIN(price) AS lowestPrice FROM BoatTours; | |
| ג | SELECT tourName, places FROM BoatTours WHERE adults + kids = places; | |
| ד | SELECT SUM(adults + kids) AS totalSold FROM BoatTours; | |
| 8 | - | if (ds.Tables[0].Rows.Count == 0) Response.Redirect("noBooking.aspx"); |
| 9 | - | •(1) new DataSet()•(2) km < 100000•(3) ds•(4) str += "<tr><td>" + row["model"] + "</td><td>" + row["year"] + "</td><td>" + row["price"] + "</td></tr>";•(5) Response.Write(str); |