Проблема обновления трех таблиц, которые связаны друг с другом - PullRequest
0 голосов
/ 23 декабря 2018

Я пытаюсь обновить три таблицы в моей базе данных, которые связаны друг с другом.

Мои таблицы настроены так:

шаблоны

id
title
id_company

questioncat

id
title
ordering
tid (id of templates)

вопросов

id
question
catid (id of questioncat)
ordering

templates содержит название моего списка вопросов, questioncat содержит все категории в моем списке, а questions содержит все вопросы, относящиеся ккатегория.

Вставка этих данных работает нормально, я делаю это так:

Сначала мой PHP-скрипт получает массив, который выглядит, например, так:

Array
(
    [0] => Array
        (
            [name] => lijsttitle
            [value] => Lijst nieuw
        )

    [1] => Array
        (
            [name] => category[]
            [value] => cat1
        )

    [2] => Array
        (
            [name] => sortorder
            [value] => 1
        )

    [3] => Array
        (
            [name] => question[]
            [value] => q1
        )

    [4] => Array
        (
            [name] => category[]
            [value] => cat2
        )

    [5] => Array
        (
            [name] => sortorder
            [value] => 2
        )

    [6] => Array
        (
            [name] => question[]
            [value] => q1
        )

)

Я делаю проверку, если список уже существует, как это:

$check = '
SELECT *
FROM templates
WHERE title = "'.$conn->real_escape_string($title["value"]).'"';
$checkcon = $conn->query($check);
$check = $checkcon->fetch_assoc();
// If there is more than 1 result, update data instead of inserting
if($checkcon->num_rows > 0){

// Else insert data as new list
}else{
    // Insert template title and companyid
    $inserttemplate = '
    INSERT INTO templates (title, id_company) VALUES ("'.$conn->real_escape_string($title["value"]).'","'.$conn->real_escape_string($companyid).'")';
    $inserttemplatecon = $conn->query($inserttemplate);
    $lastinserted = $conn->inserted_id();

    $currCat = '';
    $sortorder = '';

    foreach($arr as $a) {
      $val = $a['value'];
      // handle category
      if($a['name'] == 'category[]') {
        // save cat name
        $currCat = $val;
        // init questions array
        $store[$currCat] = [];
      }else if($a['name'] == 'sortorder') {
            $sortorder = $val;
        $store[$currCat]['sortorder'] = $val;
      }else {
        // add question to question array
        $store[$currCat]['question'][] = $val;
      }
    }

    array_shift($store);
    // $key is de waarde van de categorie, $lijst is een array met alles onder de categorie
    foreach($store as $keycat => $lijst){
        $sortorder = $lijst['sortorder'];

        $insertcats = '
        INSERT INTO questioncat (title, tid, ordering) VALUES ("'.$conn->real_escape_string($keycat).'", "'.$conn->real_escape_string($lastinserted).'", "'.$conn->real_escape_string($sortorder).'")';
        $insertcatscon = $conn->query($insertcats);
        $lastinserted1 = $conn->inserted_id();

        $questionarr = $lijst['question'];

            foreach($questionarr as $q){
                $insertquestions = '
                INSERT INTO questions (question, catid) VALUES ("'.$conn->real_escape_string($q).'", "'.$conn->real_escape_string($lastinserted1).'")';
                $insertquestionscon = $conn->query($insertquestions);
            }
    }

    echo 'Uw lijst is toegevoegd';
}

Если есть 0 результатов, список не существует и добавляется в мою базу данных, которая работает нормально, но если есть более 1 результат, егоозначает, что список уже существует и его необходимо обновить.

Здесь я начинаю испытывать проблемы.

Могу ли я обновить все три таблицы в одном запросе?

Сначала я попытался обновить только имена категорий с помощью следующего кода внутри оператора if (в котором я проверяю, существует ли список шаблонов):

foreach($arr as $a) {
    $val = $a['value'];
    // handle category
    if($a['name'] == 'category[]') {
        // save cat name
        $currCat = $val;
        // init questions array
        $store[$currCat] = [];
    }else if($a['name'] == 'sortorder') {
        $sortorder = $val;
        $store[$currCat]['sortorder'] = $val;
    }else {
        // add question to question array
        $store[$currCat]['question'][] = $val;
    }

    $updatetemplate = '
    UPDATE questioncat c
    INNER JOIN templates t
    ON c.tid = t.id
    SET t.title = "'.$conn->real_escape_string($title["value"]).'",
    c.title = "'.$conn->real_escape_string($currCat).'",
    c.ordering = "'.$conn->real_escape_string($sortorder).'"
    WHERE t.title = "'.$conn->real_escape_string($getcats['title']).'"
    AND c.id = "'.$conn->real_escape_string($getcats["id"]).'"';
    $updatetemplatecon = $conn->query($updatetemplate);
    echo 'Uw lijst is gewijzigd.';
}

Но все заголовки категорийто же самое и порядок также.

Можно ли обновить три таблицы в одном запросе?В основном это три уровня: Шаблон - Категории под шаблоном - Вопросы под категорией - возможно ли это, и если да, то как?

Ответы [ 3 ]

0 голосов
/ 27 декабря 2018

Чтобы обновить три таблицы одновременно, вы должны сделать это в одной транзакции базы данных.

Если у вас есть триггеры (ON UPDATE / DELETE / INSERT) для тех таблиц, которые должны быть выполнены, какая-то база данныхтакие движки, как PostgreSQL, позволяют откладывать момент запуска триггеров .Если триггер откладывается, он будет выполнен сразу после совершения транзакции, и благодаря этому вы даже сможете обновить все типы ключей (первичный, внешний, уникальный, сложный и т. Д.).

0 голосов
/ 27 декабря 2018

Попытка обновления одним запросом не упрощает процесс.Это был бы очень сложный запрос на обновление.И все же вам нужен способ как-то идентифицировать «дочерние» строки (категорию, вопрос) для каждого «родителя» (шаблоны, категории).

Решение с несколькими запросами на обновление / вставку:

Каждая таблица имеет уникальный идентификатор в вашем примере.Вы можете использовать этот идентификатор для обновления определенных строк.В вашем массиве php (POST / GET?) У вас есть имя и значение для каждого элемента, но нет идентификатора.Просто добавьте "id" дополнительно.

Если идентификатор пустой => ВСТАВИТЬ новую строку (Этот элемент не из базы данных)

Если идентификатор определен => ОБНОВИТЬ строку с определенным идентификатором (Этот элемент уже существует и может иметьбыл изменен)

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => lijsttitle
            [value] => Lijst nieuw
        )

    [1] => Array
        (
            [id] => 17
            [name] => category[]
            [value] => cat1
        )

    [2] => Array
        (
            [name] => sortorder
            [value] => 1
        )

    [3] => Array
        (
            [id] => 35
            [name] => question[]
            [value] => q1
        )

    [4] => Array
        (
            [id] => 
            [name] => category[]
            [value] => cat2
        )

    [5] => Array
        (
            [name] => sortorder
            [value] => 2
        )

    [6] => Array
        (
            [id] => 
            [name] => question[]
            [value] => q1
        )

)
0 голосов
/ 24 декабря 2018

Возможно, вы захотите начать поиск PL / SQL-процедур, они могут сэкономить ваше кодирование и значительно повысить безопасность.

BRIEFING:

Когда происходит событиепроисходит в 1-й таблице, он может выполнять несколько событий в базе данных, событие может быть (ON DELETE, ON UPDATE или ON INSERT) с условиями AFTER и BEFORE.

PL / SQL Триггеры: Источник

ОПРЕДЕЛЕНИЕ

Триггеры - это хранимые программы, которые автоматически выполняются или запускаются при возникновении некоторых событий.

Что касается синтаксиса, он немного меняется в зависимости от того, какую СУБД вы используете.Надеюсь, мои объяснения были хорошими.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...