בוני שאילתות

הוספה, עדכון ומחיקה עם DB::update ו-DB::delete: set_var, insert, update, new_id, ערכי הקסם NULL ו-NOW(), ערכי החזרה, והמלכודות הידועות. DB::insert לא קיים.

⏱ 4 דק' קריאה 798 מילים ערוך דף זה ב-GitHub

כתיבה למסד מתבצעת דרך שני builders: DB::update($table) שמחזיר אובייקט DB_UPDATE_CLASS להוספה ולעדכון, ו-DB::delete() למחיקה. הדף מראה את כל המתודות, מה כל אחת מחזירה, איך נכתבים שדות מתורגמים, ואילו ערכים מיוחדים הליבה מזהה.

בעמוד הזה system/ הוא תיקיית הליבה הפרוסה (= api/core בריפו) ו-{admin} הוא CONFIG::$admin_url של האתר.

DB::insert לא קיים

קריאה ל-DB::insert(...) היא fatal error. הוספה היא תמיד DB::update("table")->set_var(...)->insert().

DB::update#

DB::update($table = "", $vars = []): DB_UPDATE_CLASS

שם הטבלה בלי CRM_. המתודות של האובייקט:

מתודהפרמטריםמחזירההערה
set_var($col, $val, $tbType = "conf")עמודה, ערך, סוג טבלה$this$tbType = "content" כותב לטבלת התרגום. ערך bool הופך ל-"1" / "0"
set($col, $val, ...)כמו set_var$thisשם נוסף לאותה מתודה
ChangeContentTable($tblName, $queryKey)שם טבלת תרגום ועמודת קישורלטבלאות תרגום בשם לא סטנדרטי
insert($mainLang = true)boolיוצרת שורה. אחרי ההצלחה $obj->new_id מכיל את ה-id החדש
update($whereQuery)מספר id, או אובייקט DB_QUERY_OBJECTboolמעדכנת את השורה (או כל שורות השאילתה)
affected_rows()שבורה, ראו למטה
str_or_int_val($val)ערךמחרוזת SQLהלוגיקה שמחליטה אם לצטט ערך

הוספה#

$ins = DB::update("pages");
$ins->set_var("noDelete", 0);                 // עמודה בטבלה הראשית
$ins->set_var("title", "דף חדש", "content");  // עמודה בטבלת התרגום
if ($ins->insert()) {
    $newId = $ins->new_id;
}

אפשר גם בשרשור: DB::update("pages")->set_var("noDelete", 0)->insert(), אבל אז אין לכם את האובייקט כדי לקרוא new_id.

מה insert() עושה:

  • אם לא הוגדרה אף עמודה בטבלה הראשית, היא מריצה INSERT ... (id) VALUES (DEFAULT).
  • אם הוגדרו ערכי content והטבלה <table>_content קיימת, נוצרת גם שורת תרגום עם parentId = new_id ו-langId של השפה הנוכחית (CONFIG::$lang).
  • שגיאת SQL זורקת חריגה. false חוזר רק אם פקודה החזירה ערך ריק, מקרה נדיר.

עדכון#

$up = DB::update("pages");
$up->set_var("ord", 3);
$up->set_var("title", "כותרת חדשה", "content");
$up->update($id);                // לפי id

ל-update() אפשר להעביר גם אובייקט שאילתה, והעדכון יחול על כל שורה שהוא מחזיר:

$q = DB::query("pages", ["noDelete" => 0]);
$up = DB::update("pages")->set_var("ord", 0);
$up->update($q);

פרטים שכדאי להכיר:

  • אם אין עדיין שורת תרגום לזוג (parentId, langId), היא נוצרת אוטומטית.
  • בפועל מורצת פקודת UPDATE אחת לכל id, עם JOIN לטבלת התרגום כשצריך.
  • id שלא קיים עדיין מחזיר true: אפס שורות שהושפעו אינו כשל.

ערכים מיוחדים (str_or_int_val)#

הערך שהעברתםמה נכתב ל-SQL
מחרוזת ספרות קנונית ("42")42 בלי גרשיים. "007" מצוטט
null (PHP)NULL
המחרוזות "NULL", "NOW()", "CURRENT_TIMESTAMP"נכנסות גולמיות
FUNC(expr)נכנס expr גולמי
כל דבר אחר'<escaped>'
DB::update("pages")->set_var("updated", "NOW()")->update($id);
ערכי קסם וקלט משתמש

משתמש ששולח את המחרוזת NOW() או NULL יקבל אותה כפקודה, ומחרוזת בצורת FUNC(...) מזריקה את תוכן הסוגריים. אל תעבירו קלט גולמי של משתמש ל-set_var בלי לאמת את הפורמט שלו (מספר עם (int), תאריך עם בדיקת תבנית, ערך מרשימה לבנה).

affected_rows ו-copyToAllLangs שבורות
DB_UPDATE_CLASS::affected_rows() קוראת ל-$this->query->rowCount() אבל $this->query הוא מחרוזת ריקה, ולכן אי אפשר להסתמך עליה. אם צריך לדעת כמה שורות הושפעו, שאלו את החיבור: DB::get_connection() או בדקו עם שאילתת SELECT. גם copyToAllLangs שבורה: היא קוראת מהטבלה הישנה CRM_langs, והרקורסיה שלה רצה לפני ה-INSERT הראשי. אל תשתמשו בה.

DB::delete#

DB::delete($table = "", $whereCond = [], $orderBy = "", $lang = "", $limit = null)

מקבלת את אותם פרמטרים כמו DB::query. התנאי חייב להיות מערך לא ריק או id מספרי, אחרת הפונקציה מחזירה false ולא מוחקת כלום (הגנה מפני מחיקת טבלה שלמה).

DB::delete("pages", ["id" => $id]);
DB::delete("pages", $id);

הפעולה: בוחרת את ה-id-ים התואמים, מריצה DELETE ... WHERE id IN (...), ומוחקת גם את שורות התרגום בטבלת _content לפי queryKey (ברירת מחדל parentId).

ערך ההחזרה של delete אינו bool

בהצלחה מוחזר null, ובקלט לא תקין false. אל תבדקו === true. אם צריך לאמת מחיקה, בדקו שהשורה נעלמה.

טרנזקציות#

אין עבורן API בליבה. שני דפוסים עובדים:

DB::sql("START TRANSACTION");
try {
    // ... כמה פעולות
    DB::sql("COMMIT");
} catch (Exception $e) {
    DB::sql("ROLLBACK");
    throw $e;
}

או עם ה-PDO עצמו: $pdo = DB::get_connection(); $pdo->beginTransaction();. ה-id של שורה שנוספה זמין גם ב-$pdo->lastInsertId().

ראו גם#

מצאתם טעות או חוסר? תקנו את הדף או פתחו Issue בריפו. התיעוד נכתב מתוך הקוד של ליבה 5.0.115.