码迷,mamicode.com
首页 > 数据库 > 详细

MySQL - 1093异常 - You can't specify target table 't' for update in FROM clause

时间:2015-04-10 01:04:54      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:

有一个表示地区的表,表结构与数据大概如下表。

ID NAME PARENT_ID
1 中国  
2 广东省 1
3 广州市 2
4 荔湾区 3
5 越秀区 3
6 番禺区 3
7 小谷围街道 6

现为了查询方便,需要加一列PARENT_NAME,用以表示上级地区的名称(虽然不符合第三范式,传递依赖,但有时为了业务上的可行性、便利性,可以按实际情况考虑)

ID NAME PARENT_ID PARENT_NAME
1 中国    
2 广东省 1  
3 广州市 2  
4 荔湾区 3  
5 越秀区 3  
6 番禺区 3  
7 小谷围街道 6  

附,表的DDL、DML:

技术分享
-- ----------------------------
-- Table structure for `t_area`
-- ----------------------------

CREATE TABLE `t_area` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(256) DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  `parent_name` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_area
-- ----------------------------
INSERT INTO `t_area` VALUES (1, 中国, null, null);
INSERT INTO `t_area` VALUES (2, 广东省, 1, null);
INSERT INTO `t_area` VALUES (3, 广州市, 2, null);
INSERT INTO `t_area` VALUES (4, 荔湾区, 3, null);
INSERT INTO `t_area` VALUES (5, 越秀区, 3, null);
INSERT INTO `t_area` VALUES (6, 番禺区, 3, null);
INSERT INTO `t_area` VALUES (7, 小谷围街道, 6, null);
View Code

 

这时,需要根据已有信息,更新PARENT_NAME的数据,就有了如下的SQL:

技术分享
/* [Err] 1093 - You can‘t specify target table ‘t‘ for update in FROM clause */
update t_area t set t.parent_name = (select t2.name from t_area t2 where t.parent_id = t2.id);
View Code

报出“1093 - You can‘t specify target table ‘t‘ for update in FROM clause”的异常。意思,意思大约为,你不能指定更新的目标表在FROM子句中(英文不好,即使认识各个单词,串起来就不行了。。。)

就如文档所述“Currently, you cannot update a table and select from the same table in a subquery.”,见http://dev.mysql.com/doc/refman/5.5/en/update.html。

不知道MySQL为什么不允许这样操作,猜,可能是担心更新的表与查询的表为同一表会存在嵌套递归?还是担心效率的问题呢?

 

如果,将该表在嵌套一层,即“(select * from t_area) st”这样得出一个临时的结果集,即无报错,但,这性能较差,仅仅适合较小的数据量的。(见此讨论帖:http://stackoverflow.com/questions/17742214/you-cant-specify-target-table-name-for-update-in-from-clause)。

修改后如下:

技术分享
--ok
update t_area t set t.parent_name = (select t2.name from (select * from t_area) t2 where t.parent_id = t2.id);
View Code

 

具体针对这个需求,更简单的方式,貌似也可以:

技术分享
update t_area t, t_area t2 set t.parent_name = t2.name where t.parent_id = t2.id;
View Code

 

MySQL - 1093异常 - You can't specify target table 't' for update in FROM clause

标签:

原文地址:http://www.cnblogs.com/nick-huang/p/4412818.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!