MYSQL 不允许在子查询的同时删除原表数据的解决方法

本文介绍了在MySQL中遇到特定错误(如ERROR1093)时的两种有效解决方法,一种是通过变量赋值来规避限制,另一种是使用EXISTS关键字结合相关子查询来实现目标。这些技巧对于处理外键约束导致的问题尤其有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于这个错误信息:

ERROR 1093 (HY000): You can't specify target table 'clients' for update in FROM clause

或者:

ERROR 1093 (HY000): You can't specify target table 'clients' for delete in FROM clause



一直以来我以为只有一种办法。不过今天翻开以前的书,发现还有一个方法。

表结构和示例数据:

mysql> show create table branches\G

*************************** 1. row ***************************

       Table: branches

Create Table: CREATE TABLE `branches` (

  `bid` int(11) NOT NULL,

  `cid` int(11) NOT NULL,

  `bdesc` varchar(1000) NOT NULL,

  `bloc` char(2) NOT NULL,

  PRIMARY KEY (`bid`),

  KEY `cid` (`cid`),

  CONSTRAINT `branches_ibfk_1` FOREIGN KEY (`cid`) REFERENCES `clients` (`cid`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

1 row in set (0.00 sec)


mysql> select * from branches;

+------+-----+--------------------------------+------+

| bid  | cid | bdesc                          | bloc |

+------+-----+--------------------------------+------+

| 1011 | 101 | Corporate HQ                   | CA   |

| 1012 | 101 | Accounting Department          | NY   |

| 1013 | 101 | Customer Grievances Department | KA   |

| 1031 | 103 | N Region HO                    | ME   |

| 1032 | 103 | NE Region HO                   | CT   |

| 1033 | 103 | NW Region HO                   | NY   |

| 1041 | 104 | Branch Office (East)           | MA   |

| 1042 | 104 | Branch Office (West)           | CA   |

| 1101 | 110 | Head Office                    | CA   |

+------+-----+--------------------------------+------+

9 rows in set (0.00 sec)

mysql> show create table clients\G

*************************** 1. row ***************************

       Table: clients

Create Table: CREATE TABLE `clients` (

  `cid` int(11) NOT NULL,

  `cname` varchar(64) NOT NULL,

  PRIMARY KEY (`cid`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

mysql> select * from clients;

+-----+-----------------------------+

| cid | cname                       |

+-----+-----------------------------+

| 101 | JV Real Estate              |

| 102 | ABC Talent Agency           |

| 103 | DMW Trading                 |

| 104 | Rabbit Foods Inc            |

| 110 | Sharp Eyes Detective Agency |

+-----+-----------------------------+

5 rows in set (0.00 sec)


mysql> delete from clients where cid = (select clients.cid from clients left join branches using(cid) where bid is null);

ERROR 1093 (HY000): You can't specify target table 'clients' for update in FROM

clause


解决办法

1、利用变量赋值。

mysql> select @m_cid:=clients.cid from clients left join branches using(cid) where bid is null;

+---------------------+

| @m_cid:=clients.cid |

+---------------------+

|                 102 |

+---------------------+

1 row in set (0.00 sec)

mysql> delete from clients where cid = 102;

Query OK, 1 row affected (0.05 sec)


mysql> select * from clients;

+-----+-----------------------------+

| cid | cname                       |

+-----+-----------------------------+

| 101 | JV Real Estate              |

| 103 | DMW Trading                 |

| 104 | Rabbit Foods Inc            |

| 110 | Sharp Eyes Detective Agency |

+-----+-----------------------------+

4 rows in set (0.00 sec)


2、用EXISTS关键字和相关子查询:(不过这个没有之前的效率高)

mysql> insert into clients values(102,'ABC Talent Agency');

Query OK, 1 row affected (0.05 sec)


mysql> delete from clients where not exists

    -> (

    -> select * from branches where branches.cid = clients.cid

    -> );

Query OK, 1 row affected (0.06 sec)


mysql> select * from clients;

+-----+-----------------------------+

| cid | cname                       |

+-----+-----------------------------+

| 101 | JV Real Estate              |

| 103 | DMW Trading                 |

| 104 | Rabbit Foods Inc            |

| 110 | Sharp Eyes Detective Agency |

+-----+-----------------------------+

4 rows in set (0.00 sec)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值