# מערך שיעור: SQL בסיסי — Update ו-Delete<no value>

**משך:** יום לימוד מלא — 6 שעות אקדמיות (270 דקות).

**מטרת השיעור:** להשלים את ה-CRUD: הסטודנטים יעדכנו וימחקו בבטחה, יזהו "לא נמצא" ו"התנגשות", ויבינו Transaction. בסוף היום יש CRUD מלא מתוך Python, כפי שמגדיר הסילבוס.

**בסוף השיעור הסטודנטים צריכים:**

1. לכתוב UPDATE ו-DELETE לפי id, עם פרמטרים ו-commit, ולהשתמש ב-rowcount לזיהוי רשומה שלא קיימת.
2. לתפוס IntegrityError ולתרגם אותו, ולהשתמש ב-commit/rollback כדי לבצע פעולה מורכבת כ"הכול או כלום".
3. להרכיב ולבדוק מודול `db.py` מלא, עם חוזה עקבי לכל ארבע הפעולות.

**דגש קריטי:** **WHERE ב-UPDATE וב-DELETE.** להדגים (על מסד דמו!) UPDATE ו-DELETE בלי WHERE, ולראות את הנזק. הרגל "SELECT לפני" צריך להיחרט.

---

## מהלך השיעור

| חלק בשיעור | משך | הערות ודגשים |
|---|---|---|
| UPDATE | 40 דק' | SET מול WHERE (`=` בשני תפקידים). rowcount 0 ≠ שגיאה. סדר פרמטרים הפוך (באג שקט). |
| DELETE | 30 דק' | DELETE בלי WHERE על מסד דמו. מחיקה חוזרת → 0. id לא ממוחזר. Soft Delete כהערה. |
| הפסקה | 15 דק' | |
| בדיקת קיום, שגיאות ו-Transaction | 55 דק' | שתי הדרכים לבדיקת קיום. תרגום IntegrityError. **העברת מלאי עם rollback בלייב**. |
| הפסקה | 15 דק' | |
| מודול CRUD מלא | 45 דק' | לבנות יחד את `db.py` המלא. טבלת "חוזה" על הלוח. `check_crud.py`. |
| תרגול + Mini Project | 55 דק' | CRUD מוצרים, כולל `sell` עם CHECK. |
| בדוק את עצמך | 15 דק' | |

---

## דגשים להעברת השיעור

- **"חוזה" על הלוח** — לכתוב את טבלת החוזה של `db.py` (פונקציה → מה מחזירה בכל מצב) ולהשאיר אותה למחר. בנושא Students API – שרת עם מסד נתונים נוסיף לה עמודת "Status Code".
- **rowcount** הוא הכלי המרכזי של היום. סטודנטים מצפים לשגיאה כשמעדכנים או מוחקים משהו שלא קיים, ולהדגים שאין.
- **סדר פרמטרים** — באג שקט וקשה. להפיק אותו בכוונה ולראות שאין שום שגיאה.
- **Transaction** — להשתמש בהעברה בנקאית או במלאי. להראות שגם פעולה ראשונה ש"הצליחה" מתבטלת ב-rollback.
- **לא לבלוע שגיאות** — `except Exception` הוא מלכודת מוכרת. להראות איך באג ב-SQL "מתחפש" ל-404.
- **מוכנות לנושא Students API – שרת עם מסד נתונים** — לסיים עם `check_crud.py` רץ אצל כולם. מחר נחבר אותו ל-FastAPI, ומי ש-`db.py` שלו לא עובד ייתקע.

---

## מושגים

| מושג | הסבר קצר |
|---|---|
| UPDATE ... SET ... WHERE | עדכון שורות קיימות (Update). |
| DELETE FROM ... WHERE | מחיקת שורות (Delete). |
| rowcount | כמה שורות השתנו. 0 = לא נמצא. |
| executemany | אותה שאילתה עם רשימת פרמטרים. |
| Soft Delete | סימון כמחוק במקום מחיקה אמיתית. |
| IntegrityError | הפרת אילוץ (UNIQUE, NOT NULL, CHECK). |
| CHECK | אילוץ עם תנאי (`stock >= 0`). |
| UNIQUE (a, b) | ייחודיות של צירוף עמודות. |
| Transaction | כמה פעולות כיחידה אחת. |
| commit / rollback | שמירה / ביטול של כל השינויים. |
| Atomic | מתבצע כולו או לא בכלל. |
| Contract | מה פונקציה מחזירה וזורקת בכל מצב. |

---

## תרגיל חשיבה

**שאלת פתיחה (לפני Transaction):** "באפליקציית הבנק שלנו, העברה של 500 ש"ח מדנה לאבי היא שתי שאילתות: UPDATE שמוריד מדנה, ו-UPDATE שמוסיף לאבי. בין שתי השאילתות, השרת נופל (הפסקת חשמל). מה המצב במסד?"

**מהלך:**

1. בלי Transaction: דנה ירדה ב-500, ואבי לא קיבל. **500 ש"ח נעלמו.**
2. לשאול: "ואם נחליף את הסדר?" עכשיו אבי קיבל, ודנה לא ירדה: **500 ש"ח נוצרו מאוויר**. אין סדר "נכון".
3. לשאול: "מה היינו רוצים?" ולהוביל ל: או שתיהן או אף אחת.
4. להציג Transaction, ולהריץ את הדוגמה של העברת המלאי עם הכישלון.

**מה המרצה מראה בסוף:** את מצב הטבלה לפני, אחרי העברה מוצלחת, ואחרי העברה כושלת (זהה לקודם, בזכות rollback). ואז להדגיש: "בקוד היינו צריכים לבדוק הכול בעצמנו, בשני שלבים. כאן **המסד** מבטיח 'הכול או כלום'." משפט סיום: "**כסף לא נעלם ולא נוצר — וגם נתונים לא.** Transaction הוא החוזה של המסד איתנו."
