В этом конкретном случае вы можете делать то, что вы хотите. Из приведенных выше запросов я вижу, что:
- записи обновляются в первую очередь с одинаковыми значениями
- те же записи удаляются
Это имеет некоторые недостатки:
1. обновление каждой записи с помощью отдельного запроса вызывает ряд сетевых вызовов
2. предикаты в UPDATE
и DELETE
одинаковы, что затрудняет поддержание
Это можно решить так:
<delete id="updateSpotMetaDataTagIdsToDelete">
<bind name="simulatedById" value="_parameter.spotUpdate.userOwner.getSimulatedById()" />
with updated as (
UPDATE spotsmetadatatags
SET updatedate = now(),
simulatedBy = #{simulatedById},
fkuserowner = #{spotUpdate.userOwner.id},
sessionId = #{spotUpdate.userOwner.sessionId}
WHERE
id IN (
<foreach item="id" collection="spotUpdate.spotMetaDataTagIdsToDelete" separator="," >
#{id}
</foreach>
)
AND fkIdSpot = #{spotUpdate.fkIdSpot}
AND (SELECT COUNT(*)
FROM spots as s
WHERE s.id = #{spotUpdate.fkIdSpot}
AND s.fkIdOrganization = #{spotUpdate.userOwner.organization.id}) = 1
RETURNING id
)
DELETE FROM spotsmetadatatags AS s
USING updated AS u
WHERE u.id = s.id
</delete>
Таким образом, вы удаляете дублирование, вместо N
выполняется только один сетевой вызов, и запрос возвращает количество удаленных записей.