问题是这样的:
在java mybatis_plus mapper.xml文件中会有如下情况:
SELECT
pdd.id
FROM
pms_develop_demand pdd
WHERE
pdd.delFlag ='N'
AND pdd.demandId =#{demandId}
AND (pdd.deliver_process_Id IS NULL OR pdd .deliver_process_Id ='')
我这里有个select 查出来的是id 可能存在多个的情况
接下来我想更新这些id(developDemandId)的某个字段
UPDATE pms_develop_demand pdd
SET pdd.deliver_process_Id=#{processId}
WHERE pdd.id=#{developDemandId};
刚开始想的是在java里处理 进行for循环处理, 也不是不行,就是有点浪费性能,于是就在想着2句话能不能合成1个sql,于是开始合成了.
假设这个id是单个的情况,那就简单了,sql如下:
UPDATE pms_develop_demand pdd
SET pdd.deliver_process_Id = #{processId}
WHERE pdd.id = (
SELECT pdd.id
FROM pms_develop_demand pdd
WHERE pdd.delFlag = 'N'
AND pdd.demandId = #{demandId}
AND (pdd.deliver_process_Id IS NULL OR pdd.deliver_process_Id = '')
);
多个情况如下:
UPDATE pms_develop_demand pdd
SET pdd.deliver_process_Id = #{processId}
WHERE pdd.id IN (
SELECT pdd.id
FROM pms_develop_demand pdd
WHERE pdd.delFlag = 'N'
AND pdd.demandId = #{demandId}
AND (pdd.deliver_process_Id IS NULL OR pdd.deliver_process_Id = '')
);
但是,在美滋滋测试的时候 发现有这个错误:
You can‘t specify target table ‘表名‘ for update in FROM clause错误
查询资料之后才得知:在 MySQL文档中已经详细的指明了该问题。优化器默认会合并 derived table (实际上是一种特殊的subquery,它位于SQL语句中FROM子句里面,可以看做是一个单独的表)到外边的查询块,仅当强制具体化 derived table 时,这才有效。
接下来有4种办法,可以看资料里面的知识,我只用了第一种:包装子查询
修改sql为如下:
单个:
UPDATE pms_matter pm
SET pm.deliver_process_Id = #{processId}
WHERE pm.id =(
select * from
(SELECT pm.id
FROM pms_matter pm
WHERE pm.delFlag = 'N'
AND pm.developmentDemandId = #{developDemandId}
AND (pm.deliver_process_Id IS NULL OR pm.deliver_process_Id = '')) as b
);
多个:
UPDATE pms_matter pm
SET pm.deliver_process_Id = #{processId}
WHERE pm.id IN (
select * from
(SELECT pm.id
FROM pms_matter pm
WHERE pm.delFlag = 'N'
AND pm.developmentDemandId = #{developDemandId}
AND (pm.deliver_process_Id IS NULL OR pm.deliver_process_Id = '')) as b
);
推荐使用多个的情况(in),因为单个也满足!