Codeigniter / MySQL вопрос. Проверка возможности нескольких вставок перед фактической вставкой - PullRequest
2 голосов
/ 20 апреля 2010

Итак, я пытаюсь выполнить пару вставок одновременно, которые отчасти зависят друг от друга. Допустим, я делаю сайт по оценке собак. Любой может добавить собаку в мою базу данных, но при этом им также необходимо добавить предварительную оценку собаки. Другие люди могут потом оценить собаку. Отношение собак к рейтингам - это отношение один к одному: у собаки много оценок.

Это означает для моего предварительного добавления, так как у меня есть человек, который оценивает и добавляет собаку, мне нужно взять оценку и установить внешний ключ к первичному ключу собаки. Насколько я знаю, это означает, что я должен фактически добавить собаку, затем проверить, каков первичный ключ этого нового дополнения, и затем добавить это в свой рейтинг перед вставкой.

Теперь предположим, что с вставкой рейтинга что-то пошло не так, будь то слишком длинная строка или что-то, что я как-то упустил. Если оценка не пройдена, собака уже вставлена, но рейтинг - нет. В этом случае я бы хотел, чтобы собака не была добавлена ​​в первую очередь.

Означает ли это, что я должен написать код, который говорит: «Если оценка не удастся, сделайте удаление для собаки», или есть способ предсказать, каким будет ключ для собаки, если все пойдет как запланировано. Есть ли способ сказать «держи это место», а затем, если все работает, добавить его?

Любая помощь будет принята с благодарностью. Спасибо !!

Ответы [ 2 ]

6 голосов
/ 20 апреля 2010

CodeIgniter упрощает этот процесс с помощью транзакций.

http://codeigniter.com/user_guide/database/transactions.html

ПРИМЕЧАНИЕ:

В MySQL вам нужно будет запустить Типы таблиц InnoDB или BDB, а не более распространенный MyISAM.

$this->db->trans_start();
$this->db->query('INSERT YOUR DOG');
$this->db->query('INSERT YOUR RATING');
$this->db->trans_complete();

if ($this->db->trans_status() === FALSE)
{
    // Something went wrong, but nothing was committed to the database so you can handle the error here
}
else {
    // Everything was added fine
}
3 голосов
/ 20 апреля 2010

Добро пожаловать на землю транзакций ! Я уверен, что вам понравится ваше пребывание, потому что транзакции были изобретены специально для этой проблемы. :)

По сути, последовательность событий будет выглядеть примерно так в MySQL:

START TRANSACTION;
INSERT INTO dogs ...;
INSERT INTO dog_ratings...;
COMMIT;

Теперь в своем коде вы можете выполнять любые действия между этими запросами и завершать транзакцию в любое время, используя SQL-запрос ROLLBACK. Когда вы делаете это, ни один из запросов в рамках вашей транзакции не сохраняется в базе данных. Вы должны будете сделать его специфичным для CodeIgniter, но в основном это будет выглядеть примерно так:

$db->query("START TRANSACTION");
try {
    $db->query("INSERT INTO dogs...");
    //did that work?  Sweet.  Run the next one. You can fetch the insert id
    //here too, if you want to use it in the next query.
    $db->query("INSERT INTO dog_ratings...");
    $db->query("COMMIT");
} 
catch (DatabaseException $e)
{
    $db->query("ROLLBACK");
    echo "Problem!  ".$e->getMessage();
}

В приведенном выше коде, предполагая, что $db - это некий объект-обертка базы данных, который будет выдавать DatabaseException при сбое запроса, тогда не будет создано никаких записей , если возникнет проблема с любой из запросов внутри транзакции.

Есть много, чтобы узнать о транзакциях, так что гуглите немного. Главное, на что нужно обратить внимание, это то, что с MySQL вам необходимо использовать таблицы InnoDB для поддержки транзакций. Если вы используете MyISAM, такие команды, как START TRANSACTION и COMMIT будут выполняться, но они ничего не делают.

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