דילוג לתוכן המרכזי

בגרות במדעי המחשב תכנות באינטרנט 899372 - קיץ 2026

נבחנים אקסטרניים · שאלון 899372 · 9 שאלות · 2 שעות · פתרון מלא לכל סעיף

בחינת הבגרות במדעי המחשב, תכנות באינטרנט, קיץ 2026, כל 9 השאלות כמו בשאלון. לכל סעיף יש תשובה ופתרון מלא: הרעיון, הקוד או המעקב, ובדיקה קצרה. כל קוד מופיע ב-Java וב-C#. נסו לפתור לבד, ואז פתחו את הפתרון.

הוראות הבחינה (כמו בשאלון)

א. משך הבחינה: שעתיים.

ב. מבנה השאלון ומפתח הערכה:

פרקנקודות
פרק ראשון(10*3)30 נקודות
פרק שני(20*2) + (10*1)50 נקודות
פרק שלישי(20*1)20 נקודות
סך הכול100 נקודות

ג. חומר עזר מותר בשימוש: כל חומר עזר, חוץ ממחשבון שיש בו אפשרות תכנות.

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

השאלות בשאלון זה מנוסחות בלשון רבים, אף על פי כן על כל תלמידה וכל תלמיד להשיב עליהן באופן אישי.

בהצלחה!

הערה: לפי הודעת משרד החינוך "ההנחיות החדשות למענה על שאלות הבחינה" (מדעי המחשב, 899372, קיץ תשפ"ו 2026), מבנה השאלון ומפתח ההערכה שונו: בפרק ראשון יש לענות על 2 שאלות מתוך 3 שאלות, לכל שאלה – 10 נקודות, סך הכול לפרק: 20 נקודות. בפרקים שני ושלישי יש לענות על 4 שאלות מתוך שני הפרקים, לכל שאלה – 20 נקודות, סך הכול: 80 נקודות. (השאלון עצמו מדפיס את המבנה הרגיל, ולכן גם הניקוד המודפס ליד השאלות הוא הניקוד הרגיל.)

פרק ראשון

ענו על שלוש השאלות 3-1 (לכל שאלה – 10 נקודות).

שאלה 1 · תפקיד האובייקט Request

מהו תפקידו של אובייקט Request בתקשורת בין לקוח לשרת?

א. לשלוח תגובה מהשרת לדפדפן (ללקוח)
ב. להכיל את הבקשה שנשלחה מהדפדפן (מהלקוח) לשרת
ג. לשמור מידע במסד הנתונים
ד. לאמת את זהות המשתמש

מהו תפקידו של אובייקט Request בתקשורת בין לקוח לשרת?

(10 נקודות)
◂ פתרון מלא לשאלה 1

פתרון

תשובה

ב. להכיל את הבקשה שנשלחה מהדפדפן (מהלקוח) לשרת

מה נדרש – לבחור את התיאור הנכון של האובייקט Request.

רעיון – בתקשורת לקוח-שרת הדפדפן (הלקוח) שולח בקשה (Request) לשרת, והשרת מחזיר תגובה (Response). ב-ASP.NET האובייקט Request מייצג את הבקשה שהגיעה מהלקוח: דרכו השרת קורא את הנתונים שנשלחו, למשל Request.Form["userCode"] (שדות טופס שנשלחו ב-POST) או Request.QueryString["id"] (פרמטרים בכתובת).

פתרון – התשובה הנכונה: ב.

בדיקה – למה האחרות שגויות:

•א – שליחת תגובה מהשרת לדפדפן היא תפקידו של האובייקט Response (למשל Response.Write, Response.Redirect).
•ג – שמירת מידע במסד הנתונים נעשית בעזרת אובייקטי גישה לנתונים (SqlConnection, SqlCommand וכו'), לא בעזרת Request.
•ד – אימות זהות המשתמש הוא לוגיקה שהמתכנת כותב (למשל בדיקה מול טבלת משתמשים ושמירה ב-Session); Request רק מעביר את הנתונים שהמשתמש הזין.

טעות נפוצה: לבלבל בין Request (מהלקוח לשרת) לבין Response (מהשרת ללקוח).

שאלה 2 · שאילתת SQL – שירי Pop משנת 2020

במסד נתונים של אפליקציית מוזיקה מוגדרת טבלה בשם Songs ובה נתוני שירים. בטבלה העמודות הבאות:

•songId (מזהה השיר, מספר שלם)
•songName (שם השיר, טקסט)
•artist (שם האמן, טקסט)
•duration (משך השיר בדקות, מספר שלם)
•plays (מספר השמעות, מספר שלם)
•type (סוג המוזיקה, טקסט)
•releaseYear (שנת יציאה, מספר שלם)

כתבו שאילתה בשפת SQL המחזירה את שמות השירים שהושמעו יותר מ־1000 פעמים ושייכים לסוג המוזיקה Pop ויצאו בשנת 2020.

כתבו שאילתה בשפת SQL המחזירה את שמות השירים שהושמעו יותר מ־1000 פעמים ושייכים לסוג המוזיקה Pop ויצאו בשנת 2020.

(10 נקודות)
◂ פתרון מלא לשאלה 2

פתרון

תשובה

SELECT songName FROM Songs WHERE plays > 1000 AND type = 'Pop' AND releaseYear = 2020;

מה נדרש – להחזיר עמודה אחת (songName) של השירים שמקיימים שלושה תנאים יחד.

רעיון – בוחרים רק את העמודה songName מהטבלה Songs, ומסננים ב-WHERE עם שלושה תנאים שמחוברים ב-AND (כי כל התנאים צריכים להתקיים יחד):

•plays > 1000 – "יותר מ־1000" פירושו גדול ממש (1000 עצמו לא נכלל).
•type = 'Pop' – ערך טקסט נכתב בין גרשיים בודדים.
•releaseYear = 2020 – מספר נכתב בלי גרשיים.

פתרון

SQL
SELECT songName
FROM Songs
WHERE plays > 1000 AND type = 'Pop' AND releaseYear = 2020;

בדיקה – השאילתה על טבלה קטנה לדוגמה:

songNameplaystypereleaseYearנבחר?
Blinding Lights5000Pop2020כן
Levitating1000Pop2020לא (1000 אינו יותר מ־1000)
Watermelon Sugar2500Pop2019לא (שנה אחרת)
Savage3000HipHop2020לא (סוג אחר)
Dynamite1001Pop2020כן

התוצאה: Blinding Lights, Dynamite.

טעות נפוצה: לכתוב plays >= 1000 (כולל 1000), או לחבר את התנאים ב-OR במקום AND.

שאלה 3 · פלט של פעולת שרת – טבלת HTML

לפניכם פעולה בשם Func הכתובה בצד שרת. העתיקו למחברתכם את מה שיוצג בדפדפן לאחר הרצת הפעולה Func עם הפרמטר num = 6.

C#
public void Func (int num) {
   string str = "<table border = '1'>";
   for (int i = 1; i <= num; i++)
   {
      if (i % 6 == 0)
         str += "<tr><td>Fizz</td></tr>";
      else if (i % 3 == 0)
         str += "<tr><td>Buzz</td></tr>";
      else
         str += "<tr><td>" + i + "</td></tr>";
   }
   str += "</table>";
   Response.Write (str);
}

העתיקו למחברתכם את מה שיוצג בדפדפן לאחר הרצת הפעולה Func עם הפרמטר num = 6.

(10 נקודות)
◂ פתרון מלא לשאלה 3

פתרון

תשובה

טבלה עם מסגרת, עמודה אחת ו־6 שורות, מלמעלה למטה: 1, 2, Buzz, 4, 5, Fizz

מה נדרש – לא את קוד ה-HTML, אלא את מה שהדפדפן מציג אחרי שהשרת שולח לו את המחרוזת str.

רעיון – הפעולה בונה מחרוזת HTML של טבלה (border = '1' – טבלה עם מסגרת). בכל סיבוב של הלולאה (i מ־1 עד 6) נוספת שורה (<tr>) ובה תא אחד (<td>). לכן מתקבלת טבלה בעלת עמודה אחת ו־6 שורות. התוכן של כל תא נקבע לפי התנאים, ושימו לב שהבדיקה i % 6 == 0 נעשית לפני i % 3 == 0.

פתרון – מעקב:

ii % 6 == 0 ?i % 3 == 0 ?התוכן שנוסף
1לאלא<tr><td>1</td></tr>
2לאלא<tr><td>2</td></tr>
3לאכן<tr><td>Buzz</td></tr>
4לאלא<tr><td>4</td></tr>
5לאלא<tr><td>5</td></tr>
6כן(לא נבדק)<tr><td>Fizz</td></tr>

המחרוזת שנשלחת לדפדפן:

HTML
<table border = '1'><tr><td>1</td></tr><tr><td>2</td></tr><tr><td>Buzz</td></tr><tr><td>4</td></tr><tr><td>5</td></tr><tr><td>Fizz</td></tr></table>

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

1
2
Buzz
4
5
Fizz

בדיקה – עבור num = 6 מתקבלת בדיוק המחרוזת שלמעלה; התאים לפי הסדר: 1, 2, Buzz, 4, 5, Fizz.

טעות נפוצה: לכתוב Buzz עבור 6 (כי 6 מתחלק גם ב־3) – אבל התנאי הראשון i % 6 == 0 מתקיים ולכן נכתב Fizz וה-else if לא נבדק. טעות נוספת: לצייר את התאים בשורה אחת – כל תא נמצא ב-<tr> משלו, ולכן הם מוצגים זה מתחת לזה.

פרק שני

ענו על שלוש שאלות:
שאלה 4 (שאלת חובה – 10 נקודות) ועל שתיים מן השאלות 7-5 (לכל שאלה - 20 נקודות)

שאלה 4 · JavaScript – בדיקת הצפנת קוד משתמש (השלמת קוד)

באתר להזמנת כרטיסים יש שדה להזנת קוד משתמש:

HTML
<input type="text" maxlength="10" name="userCode" id="userCode" />

כדי להגן על המשתמשים, המערכת עושה שימוש בשיטת הצפנה. מחרוזת הקוד המקורית (originalCode) מומרת למחרוזת מוצפנת (encryptedCode) באופן הבא:

תווי הקוד המקורי משובצים בתוך המחרוזת המוצפנת כך שכל תו מהמחרוזת המקורית מופיע במרווח קבוע של X תווים במחרוזת המוצפנת. כלומר, התו הראשון של הקוד המקורי ממוקם במקום 0 במחרוזת המוצפנת, התו השני במקום ה- X במחרוזת המוצפנת, וכן הלאה – כל X תווים – עד להשלמת כל תווי המחרוזת המקורית (התו האחרון במחרוזת המקורית הוא גם התו האחרון במחרוזת המוצפנת).

בהתאם לכך, אם נבחר את התווים במיקומים 0, X, 2X, 3X וכן הלאה מתוך encryptedCode נקבל בחזרה את originalCode

דוגמה:

originalCode = "ACE"

encryptedCode = "ATCDE"

X = 2

דוגמה נוספת:

originalCode = "ACE"

encryptedCode = "AVBCDDE"

X = 3

הפעולה שלפניכם בודקת האם ההצפנה תקינה. בפעולה חסרים שישה ביטויים המסומנים במספרים (1)–(6).
כתבו במחברת הבחינה את המספרים (1)–(6) ואת הביטויים החסרים שכל מספר מייצג.

HTML
<script>
   function isValidCode (var originalCode, var encryptedCode, var X)
  {
     var i = 0;
     var j = 0;
  // נסרוק את שתי המחרוזות כל עוד לא הגענו לסוף שלהן
     while (_________(1)______ && _______(2)_________)
     {
        // אם התווים במיקומים המתאימים אינם שווים – הקוד אינו תקין
        if (______(3)______)
           return false;

        // נתקדם בשתי המחרוזות
        ____(4)________; // i
        _____(5)_______; // j
    }

    // אם לא סיימנו לעבור עד סוף שתי המחרוזות – הקוד אינו תקין
     if (______(6)______)
       return false;

     return true;
  }
</script>

כתבו במחברת הבחינה את המספרים (1)–(6) ואת הביטויים החסרים שכל מספר מייצג.

(10 נקודות)
◂ פתרון מלא לשאלה 4

פתרון

תשובה

(1) i < originalCode.length
(2) j < encryptedCode.length
(3) originalCode.charAt(i) != encryptedCode.charAt(j)
(4) i++
(5) j = j + X
(6) i < originalCode.length || j < encryptedCode.length

מה נדרש – להשלים שישה ביטויים בפעולה שבודקת אם encryptedCode הוא הצפנה תקינה של originalCode במרווח X.

רעיון – משתמשים בשני אינדקסים:

•i עובר על originalCode תו אחרי תו (0, 1, 2, ...);
•j עובר על encryptedCode בקפיצות של X (0, X, 2X, ...).

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

פתרון

מספרביטויהסבר
(1)i < originalCode.lengthלא הגענו לסוף המחרוזת המקורית
(2)j < encryptedCode.lengthלא חרגנו מסוף המחרוזת המוצפנת
(3)originalCode.charAt(i) != encryptedCode.charAt(j)התווים במיקומים המתאימים שונים
(4)i++מתקדמים תו אחד במקור
(5)j = j + Xמתקדמים X תווים במוצפן
(6)i < originalCode.length || j < encryptedCode.lengthלא הגענו לסוף אחת המחרוזות (נשארו בה תווים)

הפעולה המלאה:

JavaScript
function isValidCode(originalCode, encryptedCode, X)
{
    var i = 0;
    var j = 0;
    // נסרוק את שתי המחרוזות כל עוד לא הגענו לסוף שלהן
    while (i < originalCode.length && j < encryptedCode.length)
    {
        // אם התווים במיקומים המתאימים אינם שווים – הקוד אינו תקין
        if (originalCode.charAt(i) != encryptedCode.charAt(j))
            return false;

        // נתקדם בשתי המחרוזות
        i++; // i
        j = j + X; // j
    }
    // אם לא סיימנו לעבור עד סוף שתי המחרוזות – הקוד אינו תקין
    if (i < originalCode.length || j < encryptedCode.length)
        return false;

    return true;
}

הערה על כותרת הפעולה: בשאלון כתוב function isValidCode (var originalCode, var encryptedCode, var X). ב-JavaScript לא כותבים var ברשימת הפרמטרים (זו שגיאת תחביר), ולכן בפתרון הכותרת היא function isValidCode(originalCode, encryptedCode, X). אין לכך השפעה על הביטויים החסרים.

בדיקה

מעקב עבור הדוגמה הראשונה (originalCode = "ACE", encryptedCode = "ATCDE", X = 2, אורכים 3 ו־5):

ijoriginalCode.charAt(i)encryptedCode.charAt(j)שווים?
00AAכן
12CCכן
24EEכן
36––הלולאה נעצרת (3 < 3 שקר)

בסוף: i < 3 שקר, j < 5 (6 < 5) שקר ⇐ התנאי (6) שקר ⇐ מוחזר true.

התוצאות:

•isValidCode("ACE", "ATCDE", 2) → true; isValidCode("ACE", "AVBCDDE", 3) → true (שתי הדוגמאות מהשאלה).
•isValidCode("ACE", "ATCDF", 2) → false (התו האחרון שונה).
•isValidCode("ACE", "ATCD", 2) → false (המוצפנת קצרה מדי – i לא הגיע לסוף).
•isValidCode("AC", "ATCDE", 2) → false (j לא הגיע לסוף המוצפנת).

הערה (דיוק): אחרי הלולאה j כבר קפץ X מקומות מעבר לתו האחרון שנבדק, ולכן הביטוי (6) לא מזהה 1 עד X−1 תווים מיותרים בסוף המוצפנת (למשל "ACE", "ATCDEF", 2 מחזיר true). בדיקה מדויקת לגמרי להגדרה היא i < originalCode.length || j - X != encryptedCode.length - 1; בבדיקה ממוחשבת של כל המחרוזות מעל {A,B} (מקור עד אורך 3, מוצפנת עד אורך 7, X מ־1 עד 4) הגרסה המדויקת נכונה תמיד, והגרסה שבתשובה שונה ממנה רק במקרים האלה.

טעות נפוצה: לקדם את j ב-1 במקום ב-X, או לבדוק בסעיף (3) שוויון (==) במקום אי-שוויון.

שאלה 5 · Session – הפניית משתמש בחדר כושר

באתר של חדר כושר, המשתמש בוחר תוכנית אימונים.
כדי לקבוע לאיזה דף יעבור המשתמש, האתר משתמש במשתני Session הבאים:

•Session["age"]: מספר שלם המייצג את גיל המשתמש
•Session ["isMember"]: משתנה בוליאני המציין האם המשתמש מנוי (true/false)
•Session["visits"]: מספר שלם המייצג את מספר הביקורים החודשיים של המשתמש

בהתבסס על משתנים אלה, האתר מפנה את המשתמש לדף המתאים:

•אם גיל המשתמש גדול או שווה ל־18 וגם המשתמש מנוי בחדר הכושר וגם מספר הביקורים החודשיים שלו גדול או שווה ל־10 אז המשתמש מועבר לדף proWorkout.aspx
•אם גיל המשתמש גדול או שווה ל־15 וגם לפחות אחד מהתנאים מתקיים: הוא קטן מ־18 או שהוא מנוי אז המשתמש מועבר לדף basicWorkout.aspx
•שאר המשתמשים מועברים לדף home.aspx

כתבו בצד שרת קוד המתאים לדרישות.

כתבו בצד שרת קוד המתאים לדרישות.

(20 נקודות)
◂ פתרון מלא לשאלה 5

פתרון

תשובה

if (age >= 18 && isMember && visits >= 10) Response.Redirect("proWorkout.aspx");
else if (age >= 15 && (age < 18 || isMember)) Response.Redirect("basicWorkout.aspx");
else Response.Redirect("home.aspx");

מה נדרש – קוד C# בצד השרת שקורא את שלושת משתני ה-Session ומפנה (Redirect) לאחד משלושה דפים.

רעיון

1.ערכי Session נשמרים כ-object, ולכן יש להמיר אותם לטיפוס המתאים לפני השוואה: int.Parse(Session["age"].ToString()), bool.Parse(Session["isMember"].ToString()) (אפשר גם המרה ישירה (int)Session["age"], (bool)Session["isMember"] אם נשמרו כ-int ו-bool).
2.בודקים את התנאים לפי הסדר במבנה if / else if / else: קודם הדף המתקדם, אחר כך הבסיסי, ובסוף כל השאר.
3.בתנאי השני יש "וגם" ובתוכו "או" – חובה לשים סוגריים סביב ה"או": age >= 15 && (age < 18 || isMember).

פתרון (בתוך Page_Load של הדף, או בתוך אירוע לחיצה על כפתור):

C#
protected void Page_Load(object sender, EventArgs e)
{
    int age = int.Parse(Session["age"].ToString());
    bool isMember = bool.Parse(Session["isMember"].ToString());
    int visits = int.Parse(Session["visits"].ToString());

    if (age >= 18 && isMember && visits >= 10)
        Response.Redirect("proWorkout.aspx");
    else if (age >= 15 && (age < 18 || isMember))
        Response.Redirect("basicWorkout.aspx");
    else
        Response.Redirect("home.aspx");
}

בדיקה:

ageisMembervisitsדף
20true12proWorkout.aspx
18true10proWorkout.aspx (גבולות כלולים)
20true5basicWorkout.aspx (מנוי, אבל פחות מ־10 ביקורים)
16false0basicWorkout.aspx (15–17 גם בלי מנוי)
15false20basicWorkout.aspx
20false30home.aspx (בגיר שאינו מנוי)
14true30home.aspx (מתחת ל־15)

בכל הצירופים של גיל 10–25, מנוי/לא מנוי וביקורים 0–15 המשתמש מופנה לדף הנכון.

טעות נפוצה: לכתוב age >= 15 && age < 18 || isMember בלי סוגריים. האופרטור && קודם ל-||, ולכן הביטוי מתפרש כ-(age >= 15 && age < 18) || isMember, ומנוי בן 12 יופנה בטעות ל-basicWorkout.aspx. טעות נוספת: להשוות את Session["age"] ישירות למספר בלי המרה.

הקוד המלא
C#
protected void Page_Load(object sender, EventArgs e)
{
    int age = int.Parse(Session["age"].ToString());
    bool isMember = bool.Parse(Session["isMember"].ToString());
    int visits = int.Parse(Session["visits"].ToString());

    if (age >= 18 && isMember && visits >= 10)
        Response.Redirect("proWorkout.aspx");
    else if (age >= 15 && (age < 18 || isMember))
        Response.Redirect("basicWorkout.aspx");
    else
        Response.Redirect("home.aspx");
}

שאלה 6 · פעולת שרת IsFizzBuzz – סכום ספרות

נגדיר מספר FizzBuzz – מספר שלם חיובי שסכום הספרות שלו מתחלק ב-7 ללא שארית וגם המספר עצמו מתחלק ב-5 ללא שארית.

דוגמאות למספרים FizzBuzz:

•25 - סכום הספרות הוא 7 שמתחלק ב 7 ללא שארית, והמספר 25 מתחלק ב-5 ללא שארית.
•455 - סכום הספרות הוא 14 שמתחלק ב 7 ללא שארית, והמספר 455 מתחלק ב-5 ללא שארית.

דוגמאות למספרים שאינם FizzBuzz:

•52 - סכום הספרות הוא אמנם 7 (שמתחלק ב 7 ללא שארית) אך המספר 52 אינו מתחלק ב-5 ללא שארית.
•35 - סכום הספרות הוא 8 ואינו מתחלק ב-7 ללא שארית.

כתבו בצד שרת פעולה בשם IsFizzBuzz המקבלת מספר שלם חיובי – num, ומחזירה אמת אם המספר הוא FizzBuzz. אחרת, מחזירה שקר.

כתבו בצד שרת פעולה בשם IsFizzBuzz המקבלת מספר שלם חיובי – num, ומחזירה אמת אם המספר הוא FizzBuzz. אחרת, מחזירה שקר.

(20 נקודות)
◂ פתרון מלא לשאלה 6

פתרון

תשובה

אם num % 5 != 0 מחזירים false; אחרת מחשבים את סכום הספרות בלולאה (sum += n % 10; n /= 10) ומחזירים sum % 7 == 0.

מה נדרש – פעולה בוליאנית ב-C# (צד שרת) שבודקת שני תנאים: המספר מתחלק ב־5, וסכום ספרותיו מתחלק ב־7.

רעיון

•אם num % 5 != 0 – אפשר להחזיר false מיד.
•סכום הספרות מחושב בלולאה: n % 10 היא ספרת האחדות, ו-n / 10 (חלוקה בשלמים) "מוחקת" אותה. ממשיכים כל עוד n > 0. עובדים על עותק (n) כדי לא לשנות את num.
•מחזירים sum % 7 == 0.

פתרון

C#
public bool IsFizzBuzz(int num)
{
    if (num % 5 != 0)
        return false;
    int sum = 0;
    int n = num;
    while (n > 0)
    {
        sum += n % 10;
        n = n / 10;
    }
    return sum % 7 == 0;
}

בדיקה – מעקב עבור num = 455 (455 % 5 == 0, ממשיכים):

nn % 10sum
45555
45510
4414
0–הלולאה נעצרת

14 % 7 == 0 ⇐ מוחזר true.

התוצאות: 25 → True, 455 → True, 52 → False, 35 → False (כמו בשאלה); 70 → True, 5 → False, 160 → True. מספרי FizzBuzz עד 300: 25, 70, 95, 115, 160, 185, 205, 250, 275.

טעות נפוצה: לבדוק אם סכום הספרות מתחלק ב־5 (במקום המספר עצמו), או לחשב את סכום הספרות על num עצמו ואז לבדוק num % 5 אחרי הלולאה – כש-num כבר 0 (ו-0 מתחלק ב־5, כך שהבדיקה תמיד תצליח).

הקוד המלא
C#
public bool IsFizzBuzz(int num)
{
    if (num % 5 != 0)
        return false;
    int sum = 0;
    int n = num;
    while (n > 0)
    {
        sum += n % 10;
        n = n / 10;
    }
    return sum % 7 == 0;
}

שאלה 7 · SQL – טבלת SongsStats (3 מתוך 6 סעיפים)

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

•songId (מזהה השיר, מספר שלם)
•songName (שם השיר, טקסט)
•artist (שם האמן, טקסט)
•duration (משך השיר בדקות, מספר שלם)
•plays (מספר השמעות כולל, מספר שלם)
•dayPlays (מספר השמעות ביום, מספר שלם)
•nightPlays (מספר השמעות בלילה, מספר שלם)

דוגמה לטבלה ובה שירים באפליקציה:

songIdsongNameartistdurationplaysdayPlaysnightPlays
1HelloAdele4800500300
2ShapeEd3600400200
3Bad GuyBillie5300150150
4One DanceDrake2350250100

ענו על 3 מתוך 6 הסעיפים שלפניכם:

א.

כתבו שאילתה בשפת SQL המחזירה את כמות השירים בהם מספר ההשמעות הכולל (plays) גדול מ־500 וקטן מ 800.

ב.

כתבו שאילתה בשפת SQL המחזירה את מספר ההשמעות הגבוה ביותר ביום (dayPlays).

ג.

כתבו שאילתה בשפת SQL המחזירה את שמות השירים והאמנים בהם מספר ההשמעות בלילה גדול לפחות פי שניים ממספר ההשמעות ביום.

ד.

כתבו שאילתה בשפת SQL המחזירה את סך כל ההשמעות ביום (dayPlays) בכל השירים.

ה.

כתבו שאילתה בשפת SQL המחזירה את שמות השירים בהם משך השיר או קטן מ- 3 דקות או גדול מ- 5 דקות.

ו.

כתבו שאילתה בשפת SQL המחזירה את שמות האמנים שהשם שלהם מתחיל באות B או באות H.

◂ פתרון מלא לשאלה 7

סעיף א

תשובה

SELECT COUNT(*) FROM SongsStats WHERE plays > 500 AND plays < 800; (בטבלת הדוגמה: 1)

מה נדרש – מספר (כמות) השירים, לא את השירים עצמם.

רעיון – הפונקציה המצרפת COUNT(*) סופרת את השורות שעברו את הסינון. התנאי "גדול מ־500 וקטן מ־800" הוא טווח פתוח – שני אי-שוויונות חזקים המחוברים ב-AND.

פתרון

SQL
SELECT COUNT(*)
FROM SongsStats
WHERE plays > 500 AND plays < 800;

בדיקה – בטבלת הדוגמה: Hello (800) – לא, כי 800 אינו קטן מ־800; Shape (600) – כן; Bad Guy (300) ו-One Dance (350) – לא. התוצאה: 1.

טעות נפוצה: להשתמש ב-BETWEEN 500 AND 800 – BETWEEN כולל את הקצוות, ואז Hello (800) נספר בטעות.

סעיף ב

תשובה

SELECT MAX(dayPlays) FROM SongsStats; (בטבלת הדוגמה: 500)

מה נדרש – ערך אחד: מספר ההשמעות ביום הגבוה ביותר.

רעיון – הפונקציה המצרפת MAX מחזירה את הערך הגדול ביותר בעמודה.

פתרון

SQL
SELECT MAX(dayPlays)
FROM SongsStats;

בדיקה – ערכי dayPlays: 500, 400, 150, 250. התוצאה: 500.

סעיף ג

תשובה

SELECT songName, artist FROM SongsStats WHERE nightPlays >= 2 * dayPlays; (בטבלת הדוגמה: אין שורות)

מה נדרש – שתי עמודות (songName, artist) של השירים שבהם nightPlays גדול לפחות פי 2 מ-dayPlays.

רעיון – אפשר להשוות בין שתי עמודות של אותה שורה ואף לבצע עליהן חישוב בתוך WHERE. "גדול לפחות פי שניים" פירושו nightPlays ≥ 2 · dayPlays.

פתרון

SQL
SELECT songName, artist
FROM SongsStats
WHERE nightPlays >= 2 * dayPlays;

בדיקה – בטבלת הדוגמה אף שיר אינו מקיים את התנאי (למשל Hello: 300 ≥ 1000? לא; Bad Guy: 150 ≥ 300? לא), ולכן השאילתה מחזירה תוצאה ריקה – זו התשובה הנכונה עבור הדוגמה. בטבלה מורחבת שהוספנו לה את השירים Night Song (יום 100, לילה 200) ו-Late (יום 100, לילה 250) הוחזרו בדיוק שני השירים האלה (200 = 2·100 נכלל, כי "לפחות").

טעות נפוצה: להפוך את הכיוון (dayPlays >= 2 * nightPlays) או לכתוב nightPlays * 2 >= dayPlays.

סעיף ד

תשובה

SELECT SUM(dayPlays) FROM SongsStats; (בטבלת הדוגמה: 1300)

מה נדרש – סכום עמודת dayPlays על כל השורות.

רעיון – הפונקציה המצרפת SUM, בלי WHERE (כל השירים).

פתרון

SQL
SELECT SUM(dayPlays)
FROM SongsStats;

בדיקה – 500 + 400 + 150 + 250 = 1300. התוצאה: 1300.

טעות נפוצה: להשתמש ב-COUNT(dayPlays) – COUNT סופר שורות (4) ואינו מסכם ערכים.

סעיף ה

תשובה

SELECT songName FROM SongsStats WHERE duration < 3 OR duration > 5; (בטבלת הדוגמה: One Dance)

מה נדרש – שמות השירים שמשכם מחוץ לטווח 3–5 דקות.

רעיון – "או קטן מ־3 או גדול מ־5" – שני תנאים המחוברים ב-OR (שיר לא יכול להיות גם קצר מ־3 וגם ארוך מ־5, ולכן AND היה מחזיר תמיד תוצאה ריקה). הגבולות 3 ו־5 אינם נכללים.

פתרון

SQL
SELECT songName
FROM SongsStats
WHERE duration < 3 OR duration > 5;

בדיקה – משכים: 4, 3, 5, 2. רק One Dance (2) מקיים. התוצאה: One Dance. (3 ו־5 אינם נכללים: Shape ו-Bad Guy לא הוחזרו.)

טעות נפוצה: לחבר את התנאים ב-AND (duration < 3 AND duration > 5) – שאילתה כזו מחזירה תמיד תוצאה ריקה. (לעומת זאת duration NOT BETWEEN 3 AND 5 נכון.)

סעיף ו

תשובה

SELECT DISTINCT artist FROM SongsStats WHERE artist LIKE 'B%' OR artist LIKE 'H%'; (בטבלת הדוגמה: Billie)

מה נדרש – שמות האמנים ששמם מתחיל ב-B או ב-H.

רעיון – האופרטור LIKE עם תבנית: 'B%' פירושו "מתחיל ב-B ואחריו כל רצף תווים". שני התנאים מחוברים ב-OR. DISTINCT מונע הופעה כפולה של אמן שיש לו כמה שירים (לא חובה, אבל מתאים ל"שמות האמנים").

פתרון

SQL
SELECT DISTINCT artist
FROM SongsStats
WHERE artist LIKE 'B%' OR artist LIKE 'H%';

ב-Microsoft Access תו ה"כל רצף" הוא * במקום %: WHERE artist LIKE 'B*' OR artist LIKE 'H*'.

בדיקה – האמנים: Adele, Ed, Billie, Drake. רק Billie מתחיל ב-B ואין אמן שמתחיל ב-H. התוצאה: Billie. בטבלה מורחבת עם האמנים Halsey ו-Bruno הוחזרו Billie, Halsey, Bruno.

טעות נפוצה: לכתוב artist = 'B%' (השוואה רגילה, ללא LIKE – מחפש שם שהוא בדיוק "B%"), או LIKE 'B%' OR 'H%' בלי לחזור על שם העמודה.

פרק שלישי

ענו על אחת מן השאלות 9-8:

שאלה 8 · ASP.NET ומסד נתונים – בדיקת כרטיס (השלמת קוד)

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

HTML
<input type="text" name="userCode" id="userCode"/>

<input type="text" name="ticketType" id="ticketType"/>

במסד הנתונים של האתר קיימת טבלה בשם tickets ובה שתי עמודות:

userCode (טקסט), קוד משתמש (ייחודי)

ticketType (טקסט), קוד הכרטיס אותו עליו לקנות

דוגמה לתוכן הטבלה:

userCodeticketType
A123Regular
B321VIP

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

•אם קוד המשתמש לא קיים בטבלה, מעבר לעמוד notFound.aspx
•אם קוד המשתמש קיים אך סוג הכרטיס שהוזן אינו תואם לסוג הכרטיס הנדרש מהמשתמש, מעבר לעמוד wrongTicket.aspx
•אם קוד המשתמש קיים וגם סוג הכרטיס תואם, מעבר לעמוד success.aspx

עליכם להשלים את הקוד החסר.

C#
protected void CheckTicket(string connectionString)
{
   SqlConnection connection = new SqlConnection(connectionString);
   SqlCommand command = new SqlCommand();
   DataSet ds = new DataSet();
   command.CommandText = string.Format(
      "SELECT * FROM tickets WHERE userCode = {0}'",
      Request.Form["userCode"]);
   command.Connection = connection;
   connection.Open();
   SqlDataAdapter adapter = new SqlDataAdapter(command);
   adapter.Fill(ds);
   connection.Close();

   // *************** השלימו כאן ***************
}

עליכם להשלים את הקוד החסר.

(20 נקודות)
◂ פתרון מלא לשאלה 8

פתרון

תשובה

if (ds.Tables[0].Rows.Count == 0) Response.Redirect("notFound.aspx");
else if (ds.Tables[0].Rows[0]["ticketType"].ToString() != Request.Form["ticketType"]) Response.Redirect("wrongTicket.aspx");
else Response.Redirect("success.aspx");

מה נדרש – להשלים את סוף הפעולה: לפי תוצאת השאילתה שכבר נמצאת ב-ds, להפנות לאחד משלושת העמודים.

רעיון

•השאילתה מחזירה את השורות של tickets שבהן userCode שווה לקוד שהוזן. אחרי adapter.Fill(ds) התוצאה נמצאת בטבלה ds.Tables[0].
•אם מספר השורות ds.Tables[0].Rows.Count הוא 0 – הקוד לא קיים ⇐ notFound.aspx.
•אחרת יש בדיוק שורה אחת (userCode ייחודי): ds.Tables[0].Rows[0]. משווים את הערך בעמודה ticketType לסוג הכרטיס שהמשתמש הזין בטופס – Request.Form["ticketType"]. אם שונים ⇐ wrongTicket.aspx, אחרת ⇐ success.aspx.

פתרון – הקוד להשלמה (במקום ההערה "השלימו כאן"):

C#
    if (ds.Tables[0].Rows.Count == 0)
        Response.Redirect("notFound.aspx");
    else if (ds.Tables[0].Rows[0]["ticketType"].ToString() != Request.Form["ticketType"])
        Response.Redirect("wrongTicket.aspx");
    else
        Response.Redirect("success.aspx");

הערה על השאילתה המודפסת: במחרוזת "SELECT * FROM tickets WHERE userCode = {0}'" חסר הגרש הפותח לפני {0}. כיוון ש-userCode הוא טקסט, השאילתה הנכונה היא:

C#
command.CommandText = string.Format(
   "SELECT * FROM tickets WHERE userCode = '{0}'",
   Request.Form["userCode"]);

בדיקה – ההשלמה עם DataSet שמולא בתוצאת השאילתה על טבלת הדוגמה:

userCodeticketType שהוזןדף
A123Regularsuccess.aspx
B321VIPsuccess.aspx
A123VIPwrongTicket.aspx
B321RegularwrongTicket.aspx
C999VIPnotFound.aspx

השאילתה עצמה (עם הגרשים): עבור 'A123' מוחזרת השורה A123 | Regular, ועבור 'C999' – אין שורות.

טעות נפוצה: לגשת ל-ds.Tables[0].Rows[0] לפני שבודקים שיש שורות – כשהקוד לא קיים זו שגיאת ריצה. טעות נוספת: להשוות Rows[0]["ticketType"] (מטיפוס object) ישירות למחרוזת בלי ToString().

הקוד המלא
C#
    if (ds.Tables[0].Rows.Count == 0)
        Response.Redirect("notFound.aspx");
    else if (ds.Tables[0].Rows[0]["ticketType"].ToString() != Request.Form["ticketType"])
        Response.Redirect("wrongTicket.aspx");
    else
        Response.Redirect("success.aspx");

שאלה 9 · ASP.NET ו-SQL – שירים פופולריים ביום (השלמת CommandText)

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

C#
protected void PopularSongs(string connectionString)
{
   SqlConnection connection = new SqlConnection(connectionString);
   SqlCommand command = new SqlCommand();
   DataSet ds = new DataSet();
   command.Connection = connection;
  command.CommandText =____________
   // *************** השלימו כאן ***************
   connection.Open();
   SqlDataAdapter adapter = new SqlDataAdapter(command);
   adapter.Fill(ds);
   connection.Close();
   Response.Write("Number of songs: " + ds.Tables[0].Rows.Count);
}

יש להשלים את הפקודה CommandText כך שתבצע את השאילתה הבאה:

הפעולה מחזירה את שם השיר (songName) ואת מספר ההשמעות (plays) של שירים בהם מספר ההשמעות ביום גדול ממספר ההשמעות בלילה וגם האות הראשונה בשם של השיר זהה לאות הראשונה בשם של האומן.

יש להשלים את הפקודה CommandText כך שתבצע את השאילתה הבאה: הפעולה מחזירה את שם השיר (songName) ואת מספר ההשמעות (plays) של שירים בהם מספר ההשמעות ביום גדול ממספר ההשמעות בלילה וגם האות הראשונה בשם של השיר זהה לאות הראשונה בשם של האומן.

(20 נקודות)
◂ פתרון מלא לשאלה 9

פתרון

תשובה

command.CommandText = "SELECT songName, plays FROM SongsStats WHERE dayPlays > nightPlays AND LEFT(songName, 1) = LEFT(artist, 1)"; (על טבלת הדוגמה יודפס Number of songs: 0)

מה נדרש – לכתוב מחרוזת SQL ולהציב אותה ב-command.CommandText.

רעיון

•SELECT songName, plays – שתי העמודות המבוקשות, מהטבלה SongsStats.
•תנאי ראשון: dayPlays > nightPlays (גדול ממש) – השוואה בין שתי עמודות של אותה שורה.
•תנאי שני: האות הראשונה של songName שווה לאות הראשונה של artist. הפונקציה LEFT(str, 1) מחזירה את התו הראשון (ב-SQL Server וב-Access; אפשר גם SUBSTRING(songName, 1, 1) ב-SQL Server או Mid(songName, 1, 1) ב-Access).
•שני התנאים מחוברים ב-AND.

פתרון

C#
command.CommandText = "SELECT songName, plays FROM SongsStats " +
                      "WHERE dayPlays > nightPlays AND LEFT(songName, 1) = LEFT(artist, 1)";

(המחרוזת מפוצלת לשתי שורות בעזרת + רק לנוחות הקריאה; אפשר לכתוב אותה בשורה אחת.)

אותה לוגיקה בכתיב SQL אחר, שבו במקום LEFT משתמשים ב-substr:

SQL
SELECT songName, plays
FROM SongsStats
WHERE dayPlays > nightPlays AND substr(songName, 1, 1) = substr(artist, 1, 1);

בדיקה – על טבלת הדוגמה משאלה 7:

songNameartistdayPlays > nightPlays ?אות ראשונה זהה?נבחר?
HelloAdele500 > 300 כןH ≠ Aלא
ShapeEd400 > 200 כןS ≠ Eלא
Bad GuyBillie150 > 150 לאB = Bלא
One DanceDrake250 > 100 כןO ≠ Dלא

השאילתה מחזירה 0 שורות, ולכן הפעולה תדפיס Number of songs: 0. בטבלה מורחבת שהוספנו לה את Halo/Hozier (יום 600, לילה 300), Easy/Ed (יום 300, לילה 100) ו-Dreams/Drake (יום 200, לילה 300) הוחזרו Halo | 900 ו-Easy | 400 (Dreams לא, כי יש בו יותר השמעות בלילה).

טעות נפוצה: לכתוב songName LIKE artist + '%' או להשוות את השמות כולם (songName = artist) במקום את האות הראשונה בלבד; לשכוח את המירכאות סביב מחרוזת ה-SQL ואת ; בסוף שורת ה-C#.

הקוד המלא
C#
command.CommandText = "SELECT songName, plays FROM SongsStats " +
                      "WHERE dayPlays > nightPlays AND LEFT(songName, 1) = LEFT(artist, 1)";
טבלת התשובות
שאלהסעיףתשובה
1-

ב. להכיל את הבקשה שנשלחה מהדפדפן (מהלקוח) לשרת

2-

SELECT songName FROM Songs WHERE plays > 1000 AND type = 'Pop' AND releaseYear = 2020;

3-

טבלה עם מסגרת, עמודה אחת ו־6 שורות, מלמעלה למטה: 1, 2, Buzz, 4, 5, Fizz

4-

(1) i < originalCode.length
(2) j < encryptedCode.length
(3) originalCode.charAt(i) != encryptedCode.charAt(j)
(4) i++
(5) j = j + X
(6) i < originalCode.length || j < encryptedCode.length

5-

if (age >= 18 && isMember && visits >= 10) Response.Redirect("proWorkout.aspx");
else if (age >= 15 && (age < 18 || isMember)) Response.Redirect("basicWorkout.aspx");
else Response.Redirect("home.aspx");

6-

אם num % 5 != 0 מחזירים false; אחרת מחשבים את סכום הספרות בלולאה (sum += n % 10; n /= 10) ומחזירים sum % 7 == 0.

7א

SELECT COUNT(*) FROM SongsStats WHERE plays > 500 AND plays < 800; (בטבלת הדוגמה: 1)

ב

SELECT MAX(dayPlays) FROM SongsStats; (בטבלת הדוגמה: 500)

ג

SELECT songName, artist FROM SongsStats WHERE nightPlays >= 2 * dayPlays; (בטבלת הדוגמה: אין שורות)

ד

SELECT SUM(dayPlays) FROM SongsStats; (בטבלת הדוגמה: 1300)

ה

SELECT songName FROM SongsStats WHERE duration < 3 OR duration > 5; (בטבלת הדוגמה: One Dance)

ו

SELECT DISTINCT artist FROM SongsStats WHERE artist LIKE 'B%' OR artist LIKE 'H%'; (בטבלת הדוגמה: Billie)

8-

if (ds.Tables[0].Rows.Count == 0) Response.Redirect("notFound.aspx");
else if (ds.Tables[0].Rows[0]["ticketType"].ToString() != Request.Form["ticketType"]) Response.Redirect("wrongTicket.aspx");
else Response.Redirect("success.aspx");

9-

command.CommandText = "SELECT songName, plays FROM SongsStats WHERE dayPlays > nightPlays AND LEFT(songName, 1) = LEFT(artist, 1)"; (על טבלת הדוגמה יודפס Number of songs: 0)

כל האתר במבט אחד

קיצורי דרך לכל הכלים, הבגרויות והקורסים

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