בגרות במדעי המחשב תכנות באינטרנט 899282/899372 - קיץ 2024
נבחנים אקסטרניים · שאלון 899282/899372 · 9 שאלות · 2:15 שעות · פתרון מלא לכל סעיף
בחינת הבגרות במדעי המחשב, תכנות באינטרנט, קיץ 2024, כל 9 השאלות כמו בשאלון. לכל סעיף יש תשובה ופתרון מלא: הרעיון, הקוד או המעקב, ובדיקה קצרה. כל קוד מופיע ב-Java וב-C#. נסו לפתור לבד, ואז פתחו את הפתרון.
הוראות הבחינה (כמו בשאלון)
שימו לב: בבחינה זו יש הנחיות מיוחדות.
יש לענות על השאלות על פי הנחיות אלה.
הוראות לנבחן
א. משך הבחינה: שעתיים ורבע.
ב. מבנה השאלון ומפתח הערכה:
| פרק ראשון | (10*2) | 20 נקודות |
| פרק שני+ פרק שלישי | (20*4) | 80 נקודות |
| סך הכל | 100 נקודות |
ג. חומר עזר מותר בשימוש: כל חומר עזר, חוץ ממחשבון שיש בו אפשרות תכנות.
ד. הוראות מיוחדות
רשמו על הכריכה החיצונית של המחברת את סמל השאלון המתאים.
סמל בחינה תלמידי 5 יח״ל אקסטרני ונבחני משנה – 899282
סמל בחינה תלמידי 3 יח״ל (שאלון 899371) – 899372
כתבו במחברת הבחינה בלבד, רישמו ״טיוטה״ בראש כל עמוד המשמש טיוטה.
כתיבת טיוטה בדפים שאינם במחברת הבחינה עלולה לגרום לפסילת הבחינה.
השאלות בשאלון זה מנוסחות בלשון רבים, אף על פי כן על כל תלמידה וכל תלמיד להשיב עליהן באופן אישי.
בהצלחה!
פרק ראשון
ענו על שתיים מן השאלות 1-3 (לכל שאלה – 10 נקודות)
שאלה 1 · מהו HTML
מקובל להשתמש במונח HTML בתכנות בסביבת אינטרנט. מהו HTML?
העתיקו למחברת הבחינה את התשובה הנכונה מבין האפשרויות א–ד שלפניכם.
א. רכיב השומר מידע עבור האתר עצמו.
ב. אובייקט השומר מידע עבור משתמש מסויים.
ג. שפה המגדירה לדפדפן מה להציג למשתמש.
ד. קישור המאפשר מעבר לדף אינטרנט מוגדר.
העתיקו למחברת הבחינה את התשובה הנכונה מבין האפשרויות א–ד.
◂ פתרון מלא לשאלה 1
פתרון
ג. שפה המגדירה לדפדפן מה להציג למשתמש.
מה נדרש: לבחור את ההגדרה הנכונה של HTML.
רעיון: HTML (HyperText Markup Language) היא שפת סימון: קובץ HTML מורכב מתגיות (<table>, <p>, <a> …) שאומרות לדפדפן מה להציג ואיך לבנות את הדף. הדפדפן קורא את הקובץ ומציג אותו למשתמש.
פתרון – מעבר על האפשרויות:
<a href="...">), שהוא רק רכיב אחד בשפה. לא נכון.תשובה: ג.
בדיקה: כל אחת מהאפשרויות האחרות מתארת מושג אחר מהחומר (Application, Session, תגית <a>), ורק ג' מתארת שפה.
שאלה 2 · תגית לרשימה מסודרת
איזו תגית HTML משמשת ליצירת רשימה מסודרת?
א. <h1>
ב. <p>
ג. <ol>
ד. <div>
איזו תגית HTML משמשת ליצירת רשימה מסודרת?
◂ פתרון מלא לשאלה 2
פתרון
ג. <ol>
מה נדרש: לזהות את התגית שיוצרת רשימה מסודרת (ממוספרת).
רעיון: רשימה מסודרת = Ordered List, ובקיצור ol. כל פריט ברשימה נכתב בתגית <li>.
פתרון:
<h1> – כותרת ראשית (Heading 1).<p> – פסקה (Paragraph).<ol> – רשימה מסודרת (Ordered List) – הפריטים ממוספרים 1, 2, 3…<div> – מקטע (בלוק) כללי לקיבוץ רכיבים.דוגמה:
<ol>
<li>HTML</li>
<li>C#</li>
<li>SQL</li>
</ol>הדפדפן יציג: 1. HTML 2. C# 3. SQL.
תשובה: ג.
טעות נפוצה: לבלבל עם <ul> (Unordered List) – רשימה לא מסודרת, עם תבליטים במקום מספרים.
שאלה 3 · שאילתת SELECT עם תנאי כפול
במסד נתונים של כוכבי לכת מוגדרת טבלה בשם Plants ובה מאפייני הכוכבים. בטבלה יש ארבע עמודות:
א. שם כוכב הלכת (name).
ב. קוטר הכוכב בק״מ (size) .
ג. מרחק מהשמש (distance).
ד. מספר ירחים (num).
כתבו שאילתה בשפת SQL המאחזרת את שמות הכוכבים ואת המרחק שלהם מהשמש, בכוכבים בהן מספר הירחים גדול מ-1 וקוטר הכוכב קטן או שווה ל- 20,000 ק״מ.
כתבו שאילתה בשפת SQL המאחזרת את שמות הכוכבים ואת המרחק שלהם מהשמש, בכוכבים בהן מספר הירחים גדול מ-1 וקוטר הכוכב קטן או שווה ל- 20,000 ק״מ.
◂ פתרון מלא לשאלה 3
פתרון
SELECT name, distance FROM Plants WHERE num > 1 AND size <= 20000
מה נדרש: שאילתה שמחזירה שתי עמודות (name, distance) רק עבור כוכבים שמקיימים שני תנאים.
רעיון:
SELECT name, distance – רק העמודות המבוקשות (לא *).FROM Plants – שם הטבלה כפי שמופיע בשאלה.WHERE עם שני תנאים מחוברים ב-AND (שניהם חייבים להתקיים):num > 1 (גדול ממש, 1 עצמו לא נכלל);size <= 20000 (המספר נכתב בלי פסיק).פתרון:
SELECT name, distance
FROM Plants
WHERE num > 1 AND size <= 20000בדיקה: השאילתה על טבלה לדוגמה (בשאלה אין שורות): כוכבי הלכת של מערכת השמש ועוד שתי שורות גבול (קוטר 20000 וקוטר 20001, עם 3 ירחים). התקבלו רק Mars (קוטר 6792, 2 ירחים, מרחק 227.9) ושורת הגבול עם קוטר 20000 בדיוק. כדור הארץ לא נבחר (ירח אחד בלבד – לא גדול מ-1), צדק ושבתאי לא נבחרו (קוטר גדול מ-20,000), וגם שורת הגבול עם קוטר 20001 לא נבחרה.
טעות נפוצה: לכתוב num >= 1 (כולל כוכב עם ירח אחד), או לחבר את התנאים ב-OR במקום AND.
פרק שני
יש לענות על ארבע שאלות סך הכול מן הפרקים השני והשלישי (לכל שאלה – 20 נקודות)
שאלה 4 · טבלת HTML – rowspan/colspan וקישור
נועה, תלמידת מדעי המחשב, פיתחה אתר ובו מידע על שפות תכנות.
<!DOCTYPE html>
<html lang="he" >
<meta charset="utf-8"/>
<table style="width: 150px" border=2px dir="ltr">
<tr >
<td colspan=2 align="center">שפות תכנות</td>
</tr>
<tr>
<td rowspan=2>Name</td>
<td>C</td>
</tr>
<tr >
<td >Java</td>
</tr>
<tr>
<td colspan=2 align="center">Pyton</td>
</tr>
<tr >
<td colspan=2 align="center">SQL</td>
</tr>
</table>
</html>כיצד יוצג הדף? כיתבו במחברת הבחינה את מספר התשובה הנכונה מבין האפשרויות (a-d).

הוסיפו שורת קוד מתאימה ב html כך שלחיצה על המילה SQL תעביר לאתר:
https://he.wikipedia.org/wiki/SQL
◂ פתרון מלא לשאלה 4
סעיף א
a
מה נדרש: לבנות בראש את הטבלה מתוך הקוד ולבחור את התמונה המתאימה.
רעיון: עוברים שורה-שורה (<tr>) ובודקים כמה עמודות כל תא תופס (colspan) וכמה שורות (rowspan). שימו לב ל-dir="ltr": הטבלה נבנית משמאל לימין, כלומר התא הראשון בכל שורה נמצא בצד שמאל.
פתרון – בניית הטבלה (2 עמודות):
| שורה | עמודה שמאלית | עמודה ימנית |
|---|---|---|
| 1 | "שפות תכנות" – colspan=2, ממורכז (תופס את שתי העמודות) | ← |
| 2 | Name – rowspan=2 (תופס את שורות 2 ו-3) | C |
| 3 | (ממשיך Name) | Java |
| 4 | Pyton – colspan=2, ממורכז | ← |
| 5 | SQL – colspan=2, ממורכז | ← |
כלומר: כותרת על כל הרוחב, תא Name גבוה משמאל ולידו C ו-Java זה מתחת לזה, ואחר כך שתי שורות – Pyton ו-SQL – כל אחת על כל רוחב הטבלה וממורכזת. זו בדיוק תמונה a.
למה לא האחרות:
colspan=2.rowspan=2 והמילה היא "Pyton".colspan=2.תשובה: a.
בדיקה: רשת התאים של הטבלה לפי rowspan/colspan: 5 שורות ו-2 עמודות, Name תופס את שורות 2–3 בעמודה השמאלית, ו"שפות תכנות", Pyton ו-SQL תופסים כל אחד את שתי העמודות – כמו בתמונה a.
סעיף ב
<td colspan=2 align="center"><a href="https://he.wikipedia.org/wiki/SQL">SQL</a></td>
מה נדרש: להפוך את המילה SQL שבטבלה לקישור לאתר הנתון.
רעיון: קישור נוצר בתגית <a> (anchor), והכתובת שאליה עוברים נכתבת בתכונה href. הטקסט שבין <a ...> ל-</a> הוא מה שהמשתמש רואה ולוחץ עליו. לכן עוטפים את המילה SQL בתגית <a> בתוך התא הקיים.
פתרון – מחליפים את השורה
<td colspan=2 align="center">SQL</td>בשורה:
<td colspan=2 align="center"><a href="https://he.wikipedia.org/wiki/SQL">SQL</a></td>(אם רוצים שהאתר ייפתח בלשונית חדשה אפשר להוסיף target="_blank" – לא נדרש בשאלה.)
הדף המלא אחרי השינוי – בלשונית HTML.
בדיקה: מבנה הטבלה לא משתנה (התא עדיין colspan=2 וממורכז, כמו בתמונה a), ובתוכו המילה SQL היא עכשיו קישור ל-https://he.wikipedia.org/wiki/SQL.
טעות נפוצה: לכתוב את הקישור מחוץ ל-<td> (בין <tr> ל-<td>) – זה HTML לא תקין והקישור לא יופיע בתוך התא.
שאלה 5 · Session – עדכון רמה והפניה לדף
באתר ״המשחק שלי״, אנו שואפים להעניק לכל שחקן חוויה מותאמת אישית. על מנת להשיג זאת, אנו משתמשים במספר משתני Session:
בהתבסס על משתנים אלה, אנו מעדכנים את משתנה level ומפנים את השחקנים לדף המתאים להם:
א. משתמש עם ניקוד גדול מ-100 יועדכן לרמת expert ויועבר לעמוד competition.aspx
ב. משתמש עם ניקוד גדול מ-50 ונסיון שישה חודשים ומעלה יועדכן לרמת good ויועבר לעמוד match.aspx
ג. שאר המשתמשים יעודכנו לרמת basic ויועברו לדף training.aspx
כיתבו קוד המתאים לדרישות.
כיתבו קוד המתאים לדרישות.
◂ פתרון מלא לשאלה 5
פתרון
קוראים את Session["points"] ו-Session["experience"] (המרה ל-int), ואז if / else if / else: points > 100 ⇐ expert + competition.aspx; אחרת points > 50 && experience >= 6 ⇐ good + match.aspx; אחרת basic + training.aspx.
מה נדרש: קוד צד-שרת (C#, למשל ב-Page_Load) שקורא את משתני ה-Session, קובע את הרמה, שומר אותה ב-Session["level"] ומעביר את המשתמש לדף המתאים.
רעיון:
object, לכן כדי להשוות אותם למספרים צריך להמיר אותם ל-int: (int)Session["points"].if – else if – else.הסדר חשוב: משתמש עם 120 נקודות מקיים גם את "גדול מ-50", אבל הוא צריך לקבל expert – ולכן בודקים את התנאי של expert ראשון.
experience >= 6 (כולל 6).Session["level"] לפני Response.Redirect, כי Redirect מסיים את טיפול הדף הנוכחי ושולח את הדפדפן לדף אחר.פתרון – הקוד המלא בלשונית C#:
protected void Page_Load(object sender, EventArgs e)
{
int experience = (int)Session["experience"];
int points = (int)Session["points"];
if (points > 100)
{
Session["level"] = "expert";
Response.Redirect("competition.aspx");
}
else if (points > 50 && experience >= 6)
{
Session["level"] = "good";
Response.Redirect("match.aspx");
}
else
{
Session["level"] = "basic";
Response.Redirect("training.aspx");
}
}(אם ערכי ה-Session נשמרו כמחרוזות, ממירים בעזרת int.Parse(Session["points"].ToString()).)
בדיקה:
| experience | points | level | הפניה |
|---|---|---|---|
| 1 | 150 | expert | competition.aspx |
| 12 | 101 | expert | competition.aspx |
| 12 | 100 | good | match.aspx |
| 6 | 51 | good | match.aspx |
| 5 | 80 | basic | training.aspx |
| 6 | 50 | basic | training.aspx |
| 0 | 0 | basic | training.aspx |
כל המקרים, כולל מקרי הגבול (100, 50, 6 חודשים), התנהגו לפי הדרישות.
טעות נפוצה: לכתוב שלושה if נפרדים בלי else – אז משתמש עם 120 נקודות ו-8 חודשי נסיון יעמוד גם בתנאי השני, וה-level שלו עלול להידרס. וגם: לשכוח את ההמרה ל-int (אי אפשר להשוות object למספר).
protected void Page_Load(object sender, EventArgs e)
{
int experience = (int)Session["experience"];
int points = (int)Session["points"];
if (points > 100)
{
Session["level"] = "expert";
Response.Redirect("competition.aspx");
}
else if (points > 50 && experience >= 6)
{
Session["level"] = "good";
Response.Redirect("match.aspx");
}
else
{
Session["level"] = "basic";
Response.Redirect("training.aspx");
}
}שאלה 6 · מספר פשוט – בדיוק 2 ספרות שונות
נגדיר מספר פשוט – מספר שלם חיובי אשר מורכב בדיוק מ- 2 ספרות שונות:
דוגמאות למספרים פשוטים: 13311, 90, 998
דוגמאות למספרים שאינם פשוטים: 13211, 99, 123, 2
כתבו פונקציה בשם isSimple בצד שרת המקבלת מספר שלם חיובי ומחזירה אמת אם המספר פשוט. אחרת, מחזירה שקר.
כתבו פונקציה בשם isSimple בצד שרת המקבלת מספר שלם חיובי ומחזירה אמת אם המספר פשוט. אחרת, מחזירה שקר.
◂ פתרון מלא לשאלה 6
פתרון
public bool isSimple(int num) – שומרים את ספרת האחדות d1, ומחפשים ספרה שנייה d2; אם מופיעה ספרה שלישית שונה מ-d1 ומ-d2 מחזירים false; בסוף מחזירים true רק אם נמצאה d2.
מה נדרש: פונקציה בשפת C# (צד שרת) שמחזירה true אם במספר מופיעות בדיוק שתי ספרות שונות (כל ספרה יכולה לחזור כמה פעמים).
רעיון: מפרקים את המספר לספרות בעזרת % 10 (הספרה האחרונה) ו-/ 10 (הסרת הספרה האחרונה).
d1 – ספרת האחדות (הספרה הראשונה שאנחנו פוגשים).d2 – הספרה הראשונה שנמצא שהיא שונה מ-d1. בהתחלה d2 = -1 (סימן ש"עדיין לא נמצאה"; ספרה אמיתית היא תמיד 0–9).d: אם d == d1 – בסדר. אחרת: אם עוד אין d2 – שומרים d2 = d; ואם כבר יש d2 ו-d שונה גם ממנו – זו ספרה שונה שלישית ⇐ מחזירים false מיד.d2 נמצאה – יש בדיוק 2 ספרות שונות ⇐ true; אם לא – כל הספרות זהות (כמו 99 או 2) ⇐ false.פתרון – הקוד המלא בלשונית C#:
public bool isSimple(int num)
{
int d1 = num % 10;
int d2 = -1;
while (num > 0)
{
int d = num % 10;
if (d != d1)
{
if (d2 == -1)
d2 = d;
else if (d != d2)
return false;
}
num = num / 10;
}
return d2 != -1;
}בדיקה – מעקב על 13211:
| num | d | d1 | d2 | פעולה |
|---|---|---|---|---|
| 13211 | 1 | 1 | -1 | שווה ל-d1 |
| 1321 | 1 | 1 | -1 | שווה ל-d1 |
| 132 | 2 | 1 | -1 ⇐ 2 | ספרה שונה ראשונה: d2=2 |
| 13 | 3 | 1 | 2 | 3 שונה מ-1 ומ-2 ⇐ false |
ועל 13311: הספרות 1,1,3,3,1 – d1=1, d2=3, אין ספרה שלישית ⇐ true.
על כל הדוגמאות שבשאלה: 13311, 90, 998 ⇐ True; 13211, 99, 123, 2 ⇐ False (גם 90 עובד: d1=0, d2=9).
טעות נפוצה: לבדוק רק ש"יש לפחות שתי ספרות שונות" – אז 123 יחזיר בטעות true. או לשכוח את המקרה שכל הספרות זהות (99, 2), שבו צריך להחזיר false.
public bool isSimple(int num)
{
int d1 = num % 10;
int d2 = -1;
while (num > 0)
{
int d = num % 10;
if (d != d1)
{
if (d2 == -1)
d2 = d;
else if (d != d2)
return false;
}
num = num / 10;
}
return d2 != -1;
}שאלה 7 · שאילתות SQL על טבלת ספרייה
במסד נתונים של ספרייה מסוימת יש טבלה ששמה BookTable המכילה את נתוני הספרים בספריה.
העמודות בטבלה הן:
א. name (שם הספר), מסוג טקסט.
ב. total (סך כל הזמנות הספרים בשנה האחרונה), מסוג מספר שלם.
ג. quantity (כמות ספרים במלאי), סוג מספר שלם.
ד. pages (מספר עמודים), מסוג מספר שלם.
דוגמה לטבלה ובה ספרים בספריה:
| pages | quantity | total | name |
|---|---|---|---|
| 220 | 0 | 10 | מעשה בחמישה בלונים |
| 210 | 4 | 6 | הבית של יעל |
| 120 | 3 | 4 | איה פלוטו |
| 100 | 3 | 8 | העץ הנדיב |
| 250 | 0 | 12 | חתול תעלול |
| 90 | 2 | 8 | האריה שאהב תות |
יש לבחור 2 מתוך 4 הסעיפים הבאים:
כתבו שאילתה בשפת SQL המבקשת להציג את שמות הספרים וכמות במלאי של הספרים הזמינים להשאלה (כמות ספרים במלאי גדולה מ- 0).
כתבו שאילתה בשפת SQL המחזירה את סך כמות הספרים הקיימים במלאי בספרייה. בדוגמה: יוחזר 4+3+3+2 = 12
כתבו שאילתה בשפת SQL המוחקת את הספרים שהכמות במלאי היא 0.
כתבו שאילתה בשפתSQL המחזירה את ממוצע הספרים שהושאלו השנה. (בדוגמה: (10+6+4+8+12+8) / 6.0 =8 )
◂ פתרון מלא לשאלה 7
סעיף 1
SELECT name, quantity FROM BookTable WHERE quantity > 0
מה נדרש: להציג שתי עמודות (שם וכמות במלאי) רק לספרים שיש מהם במלאי.
רעיון: SELECT של שתי העמודות, ותנאי WHERE quantity > 0 מסנן את הספרים שהכמות שלהם 0.
פתרון:
SELECT name, quantity FROM BookTable WHERE quantity > 0בדיקה: על טבלת הדוגמה התקבלו 4 שורות: הבית של יעל 4, איה פלוטו 3, העץ הנדיב 3, האריה שאהב תות 2. "מעשה בחמישה בלונים" ו"חתול תעלול" (כמות 0) לא הוצגו.
סעיף 2
SELECT SUM(quantity) FROM BookTable (בדוגמה: 12)
מה נדרש: מספר אחד – סכום העמודה quantity על כל השורות.
רעיון: פונקציית הצבירה SUM מחברת את ערכי העמודה בכל השורות. אין צורך ב-WHERE: ספרים עם כמות 0 לא משנים את הסכום.
פתרון:
SELECT SUM(quantity) FROM BookTable(אפשר לתת שם לעמודת התוצאה: SELECT SUM(quantity) AS totalQuantity FROM BookTable.)
בדיקה: על טבלת הדוגמה התקבל 12 = 0+4+3+3+0+2, כמו בשאלה.
טעות נפוצה: להשתמש ב-COUNT(quantity) – זה סופר שורות (6) ולא מחבר כמויות.
סעיף 3
DELETE FROM BookTable WHERE quantity = 0
מה נדרש: למחוק מהטבלה את כל השורות שבהן quantity שווה 0.
רעיון: פקודת DELETE FROM מוחקת שורות שלמות (לכן לא כותבים שמות עמודות), ו-WHERE קובע אילו שורות.
פתרון:
DELETE FROM BookTable WHERE quantity = 0בדיקה: על טבלת הדוגמה נמחקו 2 שורות ("מעשה בחמישה בלונים" ו"חתול תעלול"), ונשארו 4 הספרים: הבית של יעל, איה פלוטו, העץ הנדיב, האריה שאהב תות.
טעות נפוצה: לשכוח את ה-WHERE – אז נמחקות כל השורות בטבלה. וגם: לכתוב DELETE * FROM – ב-SQL הסטנדרטי אין * בפקודת DELETE (ב-Access הדבר מותר).
סעיף 4
SELECT AVG(total) FROM BookTable (בדוגמה: 8)
מה נדרש: הממוצע של העמודה total (מספר ההזמנות/ההשאלות בשנה האחרונה) על כל הספרים.
רעיון: לפי הדוגמה בשאלה, (10+6+4+8+12+8) / 6.0, מחשבים את ממוצע העמודה total על כל 6 השורות. פונקציית הצבירה AVG עושה בדיוק את זה: סכום הערכים חלקי מספר השורות.
פתרון:
SELECT AVG(total) FROM BookTableבדיקה: על טבלת הדוגמה התקבל 8 (48 / 6), כמו בשאלה.
הערה: ב-SQL Server, AVG על עמודה של מספרים שלמים מחזיר מספר שלם (החלק אחרי הנקודה נחתך). בדוגמה זה לא משנה (48/6 = 8 בדיוק), אבל אם רוצים ממוצע עשרוני מדויק כמו ה-6.0 שבשאלה אפשר לכתוב SELECT AVG(total * 1.0) FROM BookTable.
טעות נפוצה: לחשב SUM(total) / COUNT(*) בעמודה שלמה – גם זו חלוקה בשלמים; או לחשב ממוצע של quantity במקום total.
פרק שלישי
יש לענות על ארבע שאלות סך הכול מן הפרקים השני והשלישי (לכל שאלה – 20 נקודות)
שאלה 8 · הוספת מועמד לטבלה בעזרת DataSet
בבסיס נתונים של בית ספר לטיסה קיימת טבלה השומרת את שמות המועמדים והגיל שלהם. בטופס הבא נדרש להוסיף את שם מועמד חדש ואת הגיל שלו לשדות אלו:
<input type="text" name="name" id="name"/>
<input type="Integer" name="age" id="age" />בבסיס הנתונים קיימת טבלה בשם users ובה שתי עמודות:
דוגמה לטבלה:
| name | age |
|---|---|
| Moshe | 21 |
| Dani | 30 |
לפניכם קטע קוד חלקי תקין של פעולה בשם AddCandidate. השלימו את הקוד החסר.
protected void AddCandidate (string connectionString){
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand();
command.CommandText = string.Format("Select * From users”);
command.Connection= connection;
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet ds = new DataSet();
adapter.Fill(ds);
string name=Request.Form["name"]
string age=Request.Form["age"]);
************************************
************************************
adapter.Update(ds)
}יש להשלים את הקוד החסר בסוף הפעולה (מסומן בכוכביות).
יש להשלים את הקוד החסר בסוף הפעולה (מסומן בכוכביות).
◂ פתרון מלא לשאלה 8
פתרון
העיקר – הוספת שורה חדשה ל-DataSet:
DataRow row = ds.Tables[0].NewRow();
row["name"] = name;
row["age"] = age;
ds.Tables[0].Rows.Add(row);ובנוסף, כדי ש-adapter.Update(ds) יוכל לכתוב את השורה למסד: SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
מה נדרש: להשלים את הקוד כך שהמועמד החדש (שם וגיל שהגיעו מהטופס) יתווסף לטבלה users במסד הנתונים.
רעיון: הקוד הנתון כבר:
Select * From users;DataSet (ds) בעותק של הטבלה (adapter.Fill(ds)) – הטבלה נמצאת ב-ds.Tables[0];Request.Form["name"], Request.Form["age"]).בסוף הפעולה adapter.Update(ds) שולח למסד את השינויים שנעשו בטבלה שב-DataSet. לכן מה שחסר הוא להוסיף את המועמד החדש כשורה לטבלה שב-DataSet:
ds.Tables[0].NewRow();ds.Tables[0].Rows.Add(row) (בלי זה השורה לא שייכת לטבלה ו-Update לא יראה אותה).פתרון – הקוד החסר (במקום הכוכביות):
DataRow row = ds.Tables[0].NewRow();
row["name"] = name;
row["age"] = age;
ds.Tables[0].Rows.Add(row);זה החלק שהשאלה בודקת. כדאי להוסיף אחריו (לפני adapter.Update(ds)) שורה אחת נוספת:
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);ה-adapter נוצר רק עם פקודת Select. ה-SqlCommandBuilder בונה עבורו אוטומטית את פקודת ה-INSERT, ובלעדיו adapter.Update(ds) נכשל (ב-ADO.NET נזרקת חריגה שאין InsertCommand).
הפעולה המלאה (עם תיקון טעויות ההקלדה שבקוד המודפס: ; חסרים, גרש סוגר ” ו-) מיותר אחרי Request.Form["age"]), ועם סגירת החיבור בסוף – בלשונית C#.
בדיקה: טבלה עם השורות Moshe 21 ו-Dani 30, כשהטופס שולח name=Noa ו-age=18. אחרי הקריאה בטבלה 3 שורות: Moshe 21, Dani 30, Noa 18. במדמה שלנו, כמו ב-ADO.NET האמיתי, בלי שורת ה-SqlCommandBuilder הקריאה ל-Update נכשלה.
טעות נפוצה: ליצור שורה ב-NewRow() ולשכוח Rows.Add(row) – אז השורה לא נוספת לטבלה ושום דבר לא נשמר במסד.
כתיבה מקוצרת: אפשר להוסיף את השורה גם בפקודה אחת, לפי סדר העמודות בטבלה: ds.Tables[0].Rows.Add(name, age);
דרך נוספת: במקום DataSet אפשר לבצע ישירות INSERT INTO users (name, age) VALUES (...) בעזרת SqlCommand ו-ExecuteNonQuery(), אבל השאלה בנויה כך שהפעולה מסתיימת ב-adapter.Update(ds), ולכן הפתרון המתאים הוא דרך ה-DataSet.
protected void AddCandidate(string connectionString)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand();
command.CommandText = string.Format("Select * From users");
command.Connection = connection;
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet ds = new DataSet();
adapter.Fill(ds);
string name = Request.Form["name"];
string age = Request.Form["age"];
// ---- הקוד החסר ----
DataRow row = ds.Tables[0].NewRow();
row["name"] = name;
row["age"] = age;
ds.Tables[0].Rows.Add(row);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
// --------------------
adapter.Update(ds);
connection.Close();
}שאלה 9 · השלמת פעולה המציגה טבלת ספרים
שאלה זו מתייחסת לטבלת הנתונים BookTable המוצגת בשאלה 7.
נציג העירייה מעוניין להפיק טבלה ובה נתוני כל הספרים בהם מספר ההזמנות השנתי קטן מ- 20.
הפונקציה מקבלת מחרוזת התחברות למסד הנתונים - connectionString ומציגה בטבלה את כל פרטי הספרים המתאימים (כפי שמוצגים בטבלה BookTable).
בפונקציה חסרים חמישה ביטויים מסומנים במספרים בין סוגריים עגולים. כתבו במחברת הבחינה את מספרי הביטויים החסרים (1) – (5) , בסדר עולה, וכתבו ליד כל מספר את הביטוי החסר שהוא מייצג.
protected void printTable(string connectionString)
{
string resultStr = "";
DataSet ds = new DataSet();
SqlConnection connection = new SqlConnection ( _____ (1)________);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = " select * from _____ (2)______ where ____(3)______";
cmd.Connection = connection;
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter(____(4)___);
adapter.fill (ds);
connection.Close();
resultStr += "<table dir=rtl><tr><th>name</th> <th> total </th><th> quantity </th>
<th> pages </th></tr>";
foreach DataRow row in ds.Tables[0].Rows)
{
(5)
}
resultStr += "</table>";
response.write (resultStr);
}כתבו במחברת הבחינה את מספרי הביטויים החסרים (1) – (5) , בסדר עולה, וכתבו ליד כל מספר את הביטוי החסר שהוא מייצג.
◂ פתרון מלא לשאלה 9
פתרון
(1) connectionString (2) BookTable (3) total < 20 (4) cmd (5) resultStr += "<tr><td>" + row["name"] + "</td><td>" + row["total"] + "</td><td>" + row["quantity"] + "</td><td>" + row["pages"] + "</td></tr>";
מה נדרש: להשלים חמישה ביטויים בפעולה ששולפת מהמסד את הספרים שמספר ההזמנות השנתי שלהם (העמודה total) קטן מ-20, ומציגה אותם בטבלת HTML.
רעיון – מעבר על הפעולה לפי הסדר:
connectionString.BookTable.total < 20.SqlDataAdapter צריך לקבל את הפקודה שהכנו (עם ה-SQL והחיבור) ⇐ cmd.row) של התוצאה ומוסיפים ל-resultStr שורת טבלה <tr> עם 4 תאים <td>, לפי סדר הכותרות (name, total, quantity, pages):resultStr += "<tr><td>" + row["name"] + "</td><td>" + row["total"] + "</td><td>"
+ row["quantity"] + "</td><td>" + row["pages"] + "</td></tr>";(אפשר גם לפי מספרי עמודות: row[0], row[1], row[2], row[3].)
פתרון – תשובה במחברת:
connectionStringBookTabletotal < 20cmdresultStr += "<tr><td>" + row["name"] + "</td><td>" + row["total"] + "</td><td>" + row["quantity"] + "</td><td>" + row["pages"] + "</td></tr>";הפעולה המלאה – בלשונית C#. בקוד המודפס יש כמה טעויות הקלדה שתיקנו בפעולה המלאה: adapter.fill ⇐ adapter.Fill, חסר ( אחרי foreach, ו-response.write ⇐ Response.Write (ב-C# יש הבדל בין אותיות גדולות לקטנות). בנוסף, המחרוזת של שורת הכותרות מודפסת על שתי שורות – ב-C# מחרוזת רגילה חייבת להיות בשורה אחת.
בדיקה:
select * from BookTable where total < 20 על טבלת הדוגמה משאלה 7: כל 6 הספרים מוחזרים (ה-total הגדול ביותר הוא 12).<tr><td>חתול תעלול</td><td>12</td><td>0</td><td>250</td></tr>, והספר הנוסף (25 הזמנות) לא מופיע.טעות נפוצה: בסעיף (3) לכתוב quantity < 20 – אבל "מספר ההזמנות השנתי" הוא total. בסעיף (5) לשכוח את <tr>/</tr> – אז כל התאים יופיעו באותה שורה.
protected void printTable(string connectionString)
{
string resultStr = "";
DataSet ds = new DataSet();
SqlConnection connection = new SqlConnection(connectionString); // (1)
SqlCommand cmd = new SqlCommand();
cmd.CommandText = " select * from BookTable where total < 20"; // (2), (3)
cmd.Connection = connection;
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter(cmd); // (4)
adapter.Fill(ds);
connection.Close();
resultStr += "<table dir=rtl><tr><th>name</th> <th> total </th><th> quantity </th><th> pages </th></tr>";
foreach (DataRow row in ds.Tables[0].Rows)
{
resultStr += "<tr><td>" + row["name"] + "</td><td>" + row["total"] + "</td><td>"
+ row["quantity"] + "</td><td>" + row["pages"] + "</td></tr>"; // (5)
}
resultStr += "</table>";
Response.Write(resultStr);
}טבלת התשובות
| שאלה | סעיף | תשובה |
|---|---|---|
| 1 | - | ג. שפה המגדירה לדפדפן מה להציג למשתמש. |
| 2 | - | ג. |
| 3 | - |
|
| 4 | א | a |
| ב |
| |
| 5 | - | קוראים את Session["points"] ו-Session["experience"] (המרה ל-int), ואז if / else if / else: points > 100 ⇐ expert + competition.aspx; אחרת points > 50 && experience >= 6 ⇐ good + match.aspx; אחרת basic + training.aspx. |
| 6 | - |
|
| 7 | 1 |
|
| 2 |
| |
| 3 |
| |
| 4 |
| |
| 8 | - | העיקר – הוספת שורה חדשה ל-DataSet: C# ובנוסף, כדי ש- |
| 9 | - | (1) |