Mysql You can‘t specify target table ‘表名‘ for update in FROM clause错误解决方案

测试表结构及测试数据


-- 示例:创建测试表
CREATE TABLE `b_schedule` (
  `id` varchar(255) NOT NULL COMMENT '主键ID',
  `name` varchar(255) DEFAULT NULL COMMENT '事项名称',
  `code` varchar(255) DEFAULT NULL COMMENT '编码',
  `parent_code` text COMMENT '父级编码',
  `status` varchar(64) DEFAULT NULL COMMENT '状态',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='业务事项表';



-- 初始化测试数据
INSERT INTO `zciid-deliverable`.`b_schedule` (`id`, `name`, `code`, `parent_code`, `status`) VALUES ('001', '测试1', '1', 'root', NULL);
INSERT INTO `zciid-deliverable`.`b_schedule` (`id`, `name`, `code`, `parent_code`, `status`) VALUES ('002', '测试1.1', '1.1', '001', NULL);
INSERT INTO `zciid-deliverable`.`b_schedule` (`id`, `name`, `code`, `parent_code`, `status`) VALUES ('003', '测试1.1.1', '1.1.1', '001,002', NULL);
INSERT INTO `zciid-deliverable`.`b_schedule` (`id`, `name`, `code`, `parent_code`, `status`) VALUES ('004', '测试1.2', '1.2', '001', NULL);
INSERT INTO `zciid-deliverable`.`b_schedule` (`id`, `name`, `code`, `parent_code`, `status`) VALUES ('005', '测试1.2.1', '1.2.1', '001,004', NULL);
INSERT INTO `zciid-deliverable`.`b_schedule` (`id`, `name`, `code`, `parent_code`, `status`) VALUES ('006', '测试1.2.2', '1.2.2', '001,004', NULL);
INSERT INTO `zciid-deliverable`.`b_schedule` (`id`, `name`, `code`, `parent_code`, `status`) VALUES ('007', '测试1.2.2.1', '1.2.2.1', '001,004,006', NULL);



表测试数据如下:

idnamecodeparent_codestatus
001测试11root
002测试1.11.1001
003测试1.1.11.1.1001,002
004测试1.21.2001
005测试1.2.11.2.1001,004
006测试1.2.21.2.2001,004
007测试1.2.2.11.2.2.1001,004,006

现有需求如下:

1. 更新 code 开始以 1.2 的数据 status 的值为 1;

1.1 错误的写法(及报错信息);


UPDATE `b_schedule`	
SET status = '1'
-- SET detail_floor = NULL
WHERE 
	id in (
			SELECT id FROM `b_schedule` 
			WHERE
			`code` LIKE CONCAT((SELECT code from `b_schedule` where id = '004'),'%') 
);

-- 报错信息如下

[Err] 1093 - You can't specify target table 'b_schedule' for update in FROM clause

1.2 原因分析:

		在MYSQL里,不能先select出同一表中的某些值,再update这个表(在同一语句中),即不能依据
	某字段值	做判断再来更新某字段的值,解决办法是,将select得到的结果,再通过中间表select一遍,
	这样就规避了错误,这个问题只出现于mysql,mssql和oracle不会出现此问题。

2. 更新 code 开始以 1.2 的数据 status 的值为 1;

2.1 正确的写法;


UPDATE `b_schedule`	
SET status = '1'
-- SET detail_floor = NULL
WHERE 
	id in (
		SELECT id from (
			SELECT id FROM `b_schedule` 
			WHERE
			`code` LIKE CONCAT((SELECT code from `b_schedule` where id = '004'),'%')
		) t1
);

执行结果如下:

idnamecodeparent_codestatus
001测试11root
002测试1.11.1001
003测试1.1.11.1.1001,002
004测试1.21.20011
005测试1.2.11.2.1001,0041
006测试1.2.21.2.2001,0041
007测试1.2.2.11.2.2.1001,004,0061
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值