begin;
$row = select .. from table where id=:id for update;
if ($row) {
update...
} else {
insert...
}
commit;
Ну, кстати, это наиболее правильное решение, потому что в варианте fixxxer'а между "select ... for update" и "insert" в параллельной транзакции могли вставить запись. и опаньки.а может сразу так
PHP:try{ //insert } catch(..){ // update }
А в его варианте между INSERT'ом и UPDATE'ом запись могли удалить.Ну, кстати, это наиболее правильное решение, потому что в варианте fixxxer'а между "select ... for update" и "insert" в параллельной транзакции могли вставить запись. и опаньки.
Абсолютно верно, поэтому ещё и в цикл обернуть надо, см. например в postgres'овой документации.А в его варианте между INSERT'ом и UPDATE'ом запись могли удалить.
Сравнительно с одним sql запросом с on duplicate, это АДЪ! Вам не кажется?Абсолютно верно, поэтому ещё и в цикл обернуть надо
А вот такой ещё вопрос, ко всем.в доктрине можно написать просто save() она сама разберется добавлять или обновлять.
Дык, кто ж спорит-то, хотя и в свежих версиях можно сделать без процедуры, одним запросом с WITH. Но on duplicate --- это очередная ни с чем не совместимая фишка MySQL, а описанный в стандарте MERGE, который и MySQL не умеет, --- тоже адокЪ по синтаксису и сложности реализации.Сравнительно с одним sql запросом с on duplicate, это АДЪ! Вам не кажется?![]()
у меня нет, всегда найдётся какой-то статистический запрос или запрос с кучей джойнов, подзапросов, что-то типаВопрос: Так в реальной жизни бывает?
SELECT t.*, b.title AS status, log.date_create, b.id as status_id
FROM (
SELECT cb.title AS brand, cm.title AS model, c.year, c.mileage, c.price_uah, u.phone, c.date_create as car_date_create,
(SELECT id FROM car_status_buy_log WHERE id_car=c.id ORDER BY date_create DESC LIMIT 1) AS id_status_log,
(SELECT date_create FROM car_status_buy_log WHERE id_car=c.id AND id_status=1 ORDER BY date_create ASC LIMIT 1) AS log_start,
(SELECT date_create FROM car_status_buy_log WHERE id_car=c.id AND (id_status=5 OR id_status=6) ORDER BY date_create DESC LIMIT 1) AS log_end
FROM car AS c
JOIN user AS u on u.id=c.id_user
JOIN car_dealer AS d on d.id=c.id_dealer
JOIN car_model AS cm ON cm.id=c.id_model
JOIN car_brand AS cb ON cb.id=cm.id_brand
WHERE d.code='visitor' AND c.id_status_buy!=0
ORDER BY c.date_create DESC
) AS t
LEFT JOIN car_status_buy_log AS log ON log.id=t.id_status_log
LEFT JOIN car_status_buy AS b ON b.id=log.id_status
WHERE log.id IS NULL OR b.days_expire=0 OR
(b.days_expire>0 AND DATE_SUB(NOW(), INTERVAL b.days_expire DAY) < log.date_create)
Изначально вопрос ставился - расскажите мне как оно записывается в разнокалиберных AR'ах. Если AR понимает, что от него желает юзер и сгенерит в этом случае для mysql инструкцию с onduplicate, а для постгресса с With - это будет правильный AR. а если пользоваться try-catch с циклами, то говорить о правильном AR'е уже не придется.Дык, кто ж спорит-то ... on duplicate --- это очередная ни с чем не совместимая фишка MySQL
мне напоминает это историю про 2 армии на 2х горах которые хотят напасть одновременно на вражеский. успех зависит от одновременного нападания и генерал посылает гонца "передай что нападаем в 10 утра", (они не могут напасть пока не будут уверены что другой отряд получит приказ)А в его варианте между INSERT'ом и UPDATE'ом запись могли удалить.
Ох... Да, без цикла так или иначе проблемы.Абсолютно верно, поэтому ещё и в цикл обернуть надо, см. например в postgres'овой документации.
Ага, я тут я пейсал не так давно на эту тему.Дык, кто ж спорит-то, хотя и в свежих версиях можно сделать без процедуры, одним запросом с WITH.
with, собственно, на тех же правах.on duplicate --- это очередная ни с чем не совместимая фишка MySQL
Это само собой разумеется в люблм случае, независимо от того, какой способ генерации/написания запросов используется.То есть, должно быть 100% покрытие моделями.
Говносайты и бложики - запросто. Что-то серьезное - у меня ну может две модели из ста уложились бы в ar.Никогда не пишем голый SQL, любые операции с данными - только через AR.
Не на тех же, он есть в стандарте и много кем поддерживается.with, собственно, на тех же правах.![]()
Ваще-то выход был явно обозначен: либо мы обновляем существующую запись, либо вставляем новую, не получив при этом exception.мне напоминает это историю про 2 армии на 2х горах которые хотят напасть одновременно на вражеский. успех зависит от одновременного нападания и генерал посылает гонца "передай что нападаем в 10 утра", (они не могут напасть пока не будут уверены что другой отряд получит приказ)
гонец прибегает в другой отряд и говорит о нападении, его отправляют назад чтоб он сказал что они готовы, (они не будут нападать пока не убедятся что первый отряд узнает что им извесно о нападении)
когда гонец вернулся в первый его отправляют назад чтоб он передал что они слышали что другой отряд готов
итд.
чтобы передать что они слышали что они слышали что те слышали что они нападают..
это безвыходная ситуация
Модель != AR
Я дико извиняюсь за неграмотную формулировку.Что-то серьезное - у меня ну может две модели из ста уложились бы в ar.
подразумевалось, что "доктриновский АРа разберется..." ?в доктрине можно написать просто save() она сама разберется добавлять или обновлять.