INSERT מוסיף שורות לטבלה
INSERT היא הפקודה שבה משתמשים כדי להכניס שורות חדשות לטבלה. הצורה קצרה וצפויה:
שלושה חלקים לשים לב אליהם:
INSERT INTO books: טבלת היעד.(title, author, year): העמודות שאתם מספקים להן ערכים.VALUES (...): הערכים, באותו סדר כמו ברשימת העמודות.
id לא ברשימת העמודות, ולכן SQLite מקצה אותו אוטומטית (זה INTEGER PRIMARY KEY, שמקבל את ה-rowid). כל עמודה שמדלגים עליה מקבלת את ערך ברירת המחדל שלה, או NULL אם אין כזה.
תמיד פרטו את העמודות
אפשר להשמיט את רשימת העמודות ולספק ערכים לכל עמודה לפי סדר ההצהרה:
-- עובד, אבל שביר:
INSERT INTO books VALUES (NULL, 'Dune', 'Frank Herbert', 1965);
אל תעשו את זה. ברגע שמישהו מוסיף עמודה ל-books, כל פקודה כזו נשברת או מתחילה להכניס ערכים לעמודה הלא נכונה. כתבו את העמודות במפורש:
רשימות עמודות מפורשות הן סוג של תיעוד: הן הופכות את הפקודה לקריאה בפני עצמה, בלי לחפש את הגדרת הטבלה.
הכנסה של כמה שורות
אפשר להכניס כמה שורות בפקודה אחת על ידי פירוט של עוד רשומות ערכים:
זה נקי יותר משלוש פקודות INSERT נפרדות, ו-SQLite מתייחסת להכול כפקודה אחת. עם זאת, רווח הביצועים האמיתי בטעינה המונית מגיע מעטיפת ההכנסות בטרנזקציה, ועל זה מיד.
הכנסה המונית: עטפו אותה בטרנזקציה
כברירת מחדל, כל INSERT הוא טרנזקציה בפני עצמו. SQLite מבצעת fsync בסוף כל אחד, וזה מה שהופך לולאות תמימות לאיטיות, לא ההכנסות עצמן.
קבצו אותן:
fsync אחד במקום חמישה. באלפי שורות ההבדל יכול להגיע לשניים או שלושה סדרי גודל. אם משהו בפנים נכשל, ROLLBACK מבטל את כל האצווה.
התבנית הזו היא המתכון להכנסה המונית. השתמשו בה בין אם אתם קוראים ל-SQLite מ-Python, מ-Node או מ-Rust: עטפו את הלולאה ב-BEGIN / COMMIT.
INSERT ... SELECT: העתקה מטבלה אחרת
אפשר למלא טבלה משאילתה במקום מערכים מפורשים:
העמודות מה-SELECT מותאמות לפי מיקום לרשימת העמודות של ה-INSERT. השמות לא חייבים להתאים, הסדר כן. זו הדרך המקובלת לארכב שורות, לבנות טבלאות דיווח או להעתיק תת-קבוצה של נתונים במהלך מיגרציה.
DEFAULT VALUES ועמודות שמדלגים עליהן
אם לעמודה יש פסוקית DEFAULT, אפשר להשאיר אותה מחוץ לרשימת העמודות ו-SQLite תמלא את ברירת המחדל:
created_at מקבלת את חותמת הזמן הנוכחית כי לא סיפקנו אחת. אם רוצים שורה שכולה ערכי ברירת מחדל, שימושי לשורות ממלאות מקום, השתמשו בצורה DEFAULT VALUES:
שתי שורות חדשות, בשתיהן value = 0 ומזהים שהוקצו אוטומטית.
INSERT OR IGNORE: דילוג על כפילויות
כששורה הייתה מפרה אילוץ UNIQUE או PRIMARY KEY, התנהגות ברירת המחדל היא לעצור את הפקודה עם שגיאה:
Error: UNIQUE constraint failed: users.email
INSERT OR IGNORE מחליף את זה ב"דלג בשקט על השורה הבעייתית":
שלוש שורות שורדות. הכפילות נשמטת בלי שגיאה. זו הדרך האידיומטית ב-SQLite לבטא "הכנס אם לא קיים" לנתוני seed פשוטים: בלי SELECT נפרד לבדיקה מראש, בלי טיפול בחריגות.
INSERT OR REPLACE: דריסת כפילויות
INSERT OR REPLACE מוחק את השורה המתנגשת ומכניס את החדשה במקומה:
שימו לב לדבר אחד: REPLACE הוא DELETE + INSERT, לא UPDATE. אם לשורה שנמחקה הצביעו מפתחות זרים עם ON DELETE CASCADE, גם הבנים האלה נמחקים. וכל עמודה שלא מפרטים ב-INSERT החדש מתאפסת לברירת המחדל שלה: היא לא שומרת את הערך הישן.
ברוב המקרים של "עדכן אם קיים, הכנס אם לא", מה שאתם באמת רוצים הוא upsert אמיתי עם ON CONFLICT ... DO UPDATE. יש לו עמוד משלו.
סיכום מהיר
INSERT INTO table (cols) VALUES (...): הצורה הבסיסית. תמיד פרטו עמודות.- הכנסה של כמה שורות משתמשת ברשומות מופרדות בפסיקים אחרי
VALUES. - לטעינה המונית אמיתית, עטפו את ההכנסות ב-
BEGIN/COMMIT. INSERT INTO ... SELECT ...מעתיק שורות משאילתה.DEFAULT VALUESיוצר שורה מערכי ברירת מחדל בלבד; גם עמודות שמדלגים עליהן מקבלות את ברירות המחדל שלהן.INSERT OR IGNOREמדלג על שורות מתנגשות;INSERT OR REPLACEדורס אותן (באמצעות מחיקה + הכנסה).
הצעד הבא: UPDATE
הכנסת שורות היא חצי מהסיפור. החצי השני הוא שינוי שורות שכבר קיימות: הגדלת מונה, תיקון שגיאת כתיב, סימון הזמנה כנשלחה. זה UPDATE, ויש לו סט הרגלים משלו שכדאי לעשות נכון (במיוחד פסוקית ה-WHERE). בעמוד הבא.
שאלות נפוצות
איך מכניסים שורה ב-SQLite?
השתמשו ב-INSERT INTO table (col1, col2) VALUES (val1, val2);. פירוט העמודות הוא אופציונלי אבל מומלץ מאוד: הוא שומר על הפקודה תקינה גם אם בהמשך תתווסף לטבלה עמודה חדשה. בלי רשימת עמודות, חובה לספק ערך לכל עמודה לפי סדר ההצהרה.
איך מכניסים כמה שורות בבת אחת ב-SQLite?
שימו כמה רשומות בסוגריים אחרי VALUES, מופרדות בפסיקים: INSERT INTO t (a, b) VALUES (1, 2), (3, 4), (5, 6);. לטעינה המונית אמיתית (אלפי שורות), עטפו את ההכנסות בטרנזקציה אחת עם BEGIN ו-COMMIT: משם מגיעה ההאצה, לא מתחביר השורות המרובות עצמו.
מה עושה INSERT OR IGNORE ב-SQLite?
INSERT OR IGNORE מדלג על שורות שהיו מפרות אילוץ UNIQUE, PRIMARY KEY או NOT NULL, במקום להחזיר שגיאה. השורה המתנגשת נשמטת בשקט ושאר הפקודה ממשיכה. השתמשו בו כשאתם רוצים התנהגות של 'הכנס אם עוד לא קיים' בלי בדיקת קיום נפרדת.
למה אני מקבל 'UNIQUE constraint failed' ב-INSERT?
SQLite מצאה שורה קיימת עם אותו ערך בעמודת UNIQUE או PRIMARY KEY. או שהערך באמת כפול, או שאתם מריצים שוב סקריפט seed. עברו ל-INSERT OR IGNORE כדי לדלג על כפילויות, ל-INSERT OR REPLACE כדי לדרוס אותן, או השתמשו ב-ON CONFLICT ... DO UPDATE (upsert) לשליטה מדויקת יותר.