Вопрос по sql, orm, php, doctrine – реализует «обновление, если существует» в Doctrine ORM

23

я пытаюсьINSERT OR UPDATE IF EXISTS в одной транзакции.

вmysqlЯ бы вообще использовалDUPLICATE KEY («ОБНОВЛЕНИЕ НА ДУБЛИКАТИВНОМ КЛЮЧЕ».) Мне известно о многих решениях этой проблемы с использованием различных вариантов SQL и подзапросов, но я пытаюсь реализовать это в Doctrine (PHP ORM). Кажется, что для этого существуют методы Doctrine, поскольку это так многообещающе, но я ничего не нашел. Является ли такая проблема проблемой с использованием пакетов PHP ORM по какой-то причине? Или кто-нибудь из экспертов Doctrine знает, как этого добиться с помощью хаков или каких-либо средств?

Я думаю, что вы должны пометить ответ @ pix0r как решение Mojtaba
Я начал работу над плагином для реализации этой функциональности. Он все еще находится на ранних стадиях, но протестирован и работает для моего варианта использования. Он доступен по адресу:github.com/m14t/m14tDoctrineRecordPlugin Тестовые случаи, отчеты об ошибках и запросы на получение приветствуются. m14t

Ваш Ответ

4   ответа
0

merge ($ entity); Потому что это самая близкая вещь для обновления, если существует операция, как обещано в документации:https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-objects.html

3

REPLACE INTO с использованиемreplace() метод. Это должно работать так же, какON DUPLICATE KEY UPDATE ты искал.

Docs:Замена записей

Это не решение, замена, кажется, делает удаление / вставку и изменение числовых значений (ex id)
единственная проблема с REPLACE, по-видимому, заключается в том, что он удаляет и затем создает новую строку (а не выполняет фактическое ОБНОВЛЕНИЕ), таким образом отбрасывая идентификаторы автоинкремента (в данном случае мой основной идентификатор). Я что-то здесь упускаю? например, мой идентификатор автоинкремента равен 9, но число равно 3000. Когда я выполняю REPLACE INTO для строки 9, новый идентификатор строки равен 3001. seans
REPLACE INTO не эквивалентноINSERT ... ON DUPLICATE KEY UPDATE ..., 1-й удалит строку и вставит новую. Если есть триггеры удаления или внешние ключи (даже больше сCASCADE), REPLACE не является жизнеспособным вариантом.
@ Фронкер исправлен.
выше ссылка не работает.
3

https://www.vivait.co.uk/labs/updating-entities-when-an-insert-has-a-duplicate-key-in-doctrine это может быть достигнуто с$entityManager->merge().

$entity = new Table();
$entity->setId(1);
$entity->setValue('TEST');

$entityManager->merge($entity);
$entityManager->flush();
странно, но не работает для меня. я используюstackoverflow.com/a/24384768/5809937  в симфонии 3
5

о чем я могу думать, это сначала запросить сущность, если она существует, иначе создайте новую сущность.

if(!$entity = Doctrine::getTable('Foo')->find(/*[insert id]*/))
{
   $entity = new Foo();
}
/*do logic here*/
$entity->save();
Ничто не гарантирует, что между запросом и сохранением не будет создана строка.
Разве это не то, для чего предназначены транзакции?
Очень опасно, как сказал @IliaJerebtsov, между персистом и флешем может быть скандал. В этом случае вы должны рассмотреть возможность использования чистого SQL ;-(

Похожие вопросы