Можете ли вы начать MySQL заявление с «IF»? - PullRequest
0 голосов
/ 16 июля 2009

Я пытаюсь реализовать "ЕСЛИ запись существует, то после вставки" в MySQL. В частности, я должен выяснить, как это сделать с помощью Doctrine ORM.

Одним из решений, использующих собственный MySql, является использование «ON DUPLICATE KEY UPDATE». К сожалению, это не поддерживается в доктрине.

Другим полурешением является использование синтаксиса «REPLACE INTO». Doctrine поддерживает это, однако REPLACE не обновляет записи, вместо этого он удаляет запись и создает новую (с новым идентификатором автоинкремента). Из-за этого плохое решение, если вы полагаетесь на идентификаторы автоинкремента, как и я. ,

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

Могу ли я сказать «ЕСЛИ (ВСТАВИТЬ ИГНОРИРУЕТ ВНУТРИ таблицы critical_id = $ id), ТО ВЫЙТИ из ELSE (ОБНОВИТЬ таблицу SET field = 'new_value')" внутри транзакции?

Если я не могу сказать что-то подобное, есть ли решение этой проблемы?

Ответы [ 3 ]

1 голос
/ 16 июля 2009

Либо найдите способ заставить работать «ON DUPLICATE KEY UPDATE», либо переключитесь на использование двух операторов: сначала SELECT для поиска любых существующих строк, затем UPDATE или INSERT, если необходимо.

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

1 голос
/ 16 июля 2009

«Вставить или обновить» называется «Upsert». Если вы нажмете «upsert mysql», вы обнаружите, что существует всего несколько решений.

  1. 2 шага, вставка, затем обновление и варианты
  2. "ON DUPLICATE KEY UPDATE"
  3. REPLACE

И, может быть, еще немного, но большинство из них являются вариациями.

При использовании транзакций ваш SQL будет выглядеть так:

    UPDATE xxx SET (x1, x2) = (y1, y2) WHERE id = myid;
    IF found THEN
        RETURN;
    END IF;
    BEGIN
        INSERT INTO xxx (x1, x2) VALUES (y1, y2);
        RETURN;
    EXCEPTION WHEN unique_violation THEN
    --##Do nothing, or you can put this whole sql code
    --##in a LOOP and it will loop over and try update again
    END;

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

0 голосов
/ 16 июля 2009

Вы уже упоминали INSERT IGNORE INTO. Разве это не отвечает вашим потребностям?

http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html

...