Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

SQL обновление нескольких записей одним запросом

#sql #postgresql


Есть таблица с колонкой active, в один момент времени может быть активна только одна
запись. Необходимо делать UPDATE записи и ставить значение active в true, и одновременно
ставить в false значение active в старой записи. Подскажите как это сделать одним запросом.

Пример

Исходная таблица 

id   name  active
 1     a     true
 2     b     false
 3     c     false

После 

id   name  active
 1     a     false
 2     b     true
 3     c     false
    


Ответы

Ответ 1



Update меняющий у одной записи active на true и у всех других записей, которые сейчас active на false (гарантирует, что в таблице только одна запись может быть true): with Q as ( select * from testBool where active=true or id=3 ) update testBool T set active=not T.active from Q where exists(select 1 from Q where active=false) and T.id=Q.id

Ответ 2



Есть вот такой безумный вариант: UPDATE actives SET active = (id = 1); -- ^^^^^^^^ это ж boolean! Условие будет соблюдено, если на поле выборки есть констрейнт UNIQUE, чтобы true из равенства могло выпасть лишь для одной строки таблицы. Однако, если такого ключа в таблице нет совсем, всё сбросится на false. Можно добавить условие на id, содержащее SELECT из той же таблицы, чтобы таких ситуаций избежать. Безумным я его считаю потому, что база вряд ли догадается узнать, сколько записей в результате запроса реально изменится, а мы знаем, что таких всегда не более двух. База же будет обходить все строки. Но надо измерять производительность и выяснять, возможно, эта проблема существует только в моей голове. Но даже если нет, более быстрое решение целостности ради может просто не существовать. Я не знаю. Евгений Борисов в комментариях к вопросу правильно отмечает, что гораздо эффективнее хранить в другом месте первичный ключ активной записи. Единственное место можно атомарно менять с куда меньшими блокировками.

Ответ 3



C помощью триггеров: Crteate trigger trig Before inser or update or delete on TABLE For Each ROW Execute Prosedure reset_all_to_false() Функция: Create Function reset_all_to_false() returns void Begin update table set active = false where active = true; end;

Ответ 4



возможно подойдет такой вариант ? с начало устанавливаем false update table set active = false where active = true а затем устанавливаем нужную строчку update table set active = true where условие 2 вариант update t set active = case when *условие true* then true else false end но этот вариант плох что по всей таблице пройдет можно дописать еще условия для ограничения

Комментариев нет:

Отправить комментарий