在 PostgreSQL 上一起更新和删除
Update and delete together on PostgreSQL
我的 postgreSQL 查询有问题。
我必须在之前使用 UPDATE 并在之后使用 DELETE 进行查询。
return 值是更新的数量,但我想要删除的数量。
我能怎么做?非常感谢你。
我用的是 myBatis.
<update id="updateSpotMetaDataTagIdsToDelete">
<bind name="simulatedById" value="_parameter.spotUpdate.userOwner.getSimulatedById()" />
<foreach item="id" collection="spotUpdate.spotMetaDataTagIdsToDelete" separator=";" >
UPDATE spotsmetadatatags
SET updatedate = now(),
simulatedBy = #{simulatedById},
fkuserowner = #{spotUpdate.userOwner.id},
sessionId = #{spotUpdate.userOwner.sessionId}
WHERE
id = #{id}
AND fkIdSpot = #{spotUpdate.fkIdSpot}
AND (SELECT COUNT(*)
FROM spots as s
WHERE s.id = #{spotUpdate.fkIdSpot}
AND s.fkIdOrganization = #{spotUpdate.userOwner.organization.id}) = 1
</foreach>;
DELETE FROM spotsmetadatatags
WHERE fkIdSpot = #{spotUpdate.fkIdSpot}
AND id IN (
<foreach item="id" collection="spotUpdate.spotMetaDataTagIdsToDelete" separator="," >
#{id}
</foreach>
)
AND (SELECT COUNT(*)
FROM spots as s
WHERE s.id = #{spotUpdate.fkIdSpot}
AND s.fkIdOrganization = #{spotUpdate.userOwner.organization.id}) = 1;
</update>
您可以一次执行多个 SQL 语句,但它应该属于同一个操作,如多个更新语句或多个删除语句。您不能在同一个映射器中混合更新和删除。
示例如果要删除多个 sql 语句。
<delete id="delete" parameterType="map">
DELETE FROM table_a where X=${frommap};
DELETE FROM table_b where X=${frommap};
DELETE FROM table_c where X=${frommap}
</delete>
在这种特殊情况下,您可以随心所欲。从上面的查询中我可以看到:
- 具有相同值的记录先一条一条更新
- 相同的记录被删除
这有一些低效:
- 使用单独的查询更新每条记录会导致大量网络调用
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
并且查询将 return 删除记录的数量。
我的 postgreSQL 查询有问题。 我必须在之前使用 UPDATE 并在之后使用 DELETE 进行查询。 return 值是更新的数量,但我想要删除的数量。 我能怎么做?非常感谢你。 我用的是 myBatis.
<update id="updateSpotMetaDataTagIdsToDelete">
<bind name="simulatedById" value="_parameter.spotUpdate.userOwner.getSimulatedById()" />
<foreach item="id" collection="spotUpdate.spotMetaDataTagIdsToDelete" separator=";" >
UPDATE spotsmetadatatags
SET updatedate = now(),
simulatedBy = #{simulatedById},
fkuserowner = #{spotUpdate.userOwner.id},
sessionId = #{spotUpdate.userOwner.sessionId}
WHERE
id = #{id}
AND fkIdSpot = #{spotUpdate.fkIdSpot}
AND (SELECT COUNT(*)
FROM spots as s
WHERE s.id = #{spotUpdate.fkIdSpot}
AND s.fkIdOrganization = #{spotUpdate.userOwner.organization.id}) = 1
</foreach>;
DELETE FROM spotsmetadatatags
WHERE fkIdSpot = #{spotUpdate.fkIdSpot}
AND id IN (
<foreach item="id" collection="spotUpdate.spotMetaDataTagIdsToDelete" separator="," >
#{id}
</foreach>
)
AND (SELECT COUNT(*)
FROM spots as s
WHERE s.id = #{spotUpdate.fkIdSpot}
AND s.fkIdOrganization = #{spotUpdate.userOwner.organization.id}) = 1;
</update>
您可以一次执行多个 SQL 语句,但它应该属于同一个操作,如多个更新语句或多个删除语句。您不能在同一个映射器中混合更新和删除。
示例如果要删除多个 sql 语句。
<delete id="delete" parameterType="map">
DELETE FROM table_a where X=${frommap};
DELETE FROM table_b where X=${frommap};
DELETE FROM table_c where X=${frommap}
</delete>
在这种特殊情况下,您可以随心所欲。从上面的查询中我可以看到:
- 具有相同值的记录先一条一条更新
- 相同的记录被删除
这有一些低效:
- 使用单独的查询更新每条记录会导致大量网络调用
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
并且查询将 return 删除记录的数量。