在PostgreSQL上一起更新和删除

时间:2019-07-01 08:58:05

标签: java postgresql mybatis

我的postgreSQL查询有问题。 我必须使用UPDATE之前和之后的DELETE进行查询。 返回值是UPDATE的数量,但我想要DELETE的数量。 我能怎么做?非常感谢你。 我使用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>

2 个答案:

答案 0 :(得分:1)

在这种情况下,您可以做自己想做的事情。从上面的查询中,我可以看到:

  1. 记录将首先使用相同的值一次更新
  2. 相同的记录被删除

这效率低下: 1.使用单独的查询更新每个记录会导致大量网络调用 2. UPDATEDELETE中的谓词相同,因此难以维护

可以这样解决:

<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,查询将返回删除记录的数量。

答案 1 :(得分:0)

您可以一次执行多个SQL语句,但是它应该属于同一操作,例如,多个Update语句或多个Delete语句。您不能在同一映射器中混用更新和删除。

示例,如果要使用多个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>