【问题标题】:You can't specify target table 'creature' for update in FROM clause您不能在 FROM 子句中指定目标表 'creature' 进行更新
【发布时间】:2017-01-12 23:29:13
【问题描述】:

我有一个包含游戏生物的数据库。

2 个表:

“creature_template”包含与生物相关的所有数据

“生物”包含有关游戏中生物位置的信息。

代码如下:

    DELETE FROM 
     creature 
    WHERE 
     id not in 
    (SELECT DISTINCT 
     b.id 
    FROM 
     creature_template a inner join creature b on a.entry = b.id 
    WHERE 
     b.map != 571 
     AND a.`type` = 1 
     AND a.`type` = 10
    );

类型是生物的类型(1 = 野兽,10 = 未指定)

我要做的是删除地图#571上所有不是野兽(type=1)或未指定(type=10)的生物。

“map”列在“creature”表中,而“type”列在“creature_template”表中。

游戏中的每个生物都在数据库中通过 ID 进行标识。 “creature”表有一个名为“id”的列,其中包含这些 ID,而“creature_template”表中的等效项是一个名为“entry”的列。

所以我必须做的是选择地图#571上的所有生物,然后排除所有类型1和10并删除其余的。

问题是当我执行上面的代码时,我收到错误消息“您不能在 FROM 子句中指定目标表 'creature' 进行更新”

我在这里对 stackoverflow 进行了一些研究,并尝试了一些我找到的解决方案。

...我最终从“生物”表中删除了所有数据。幸运的是,我从昨天做的备份中取回了数据。

知道如何解决我的问题吗?

【问题讨论】:

  • 如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做,请提供适当的 CREATE 和 INSERT 语句(和/或 sqlfiddle),以便我们可以更容易复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。

标签: mysql


【解决方案1】:

一种可能性是INSERT INTO a temp table 使用SELECTcreature 中提取要删除的行或要保留的行(临时表只需要包含PK 列),然后在WHERE DELETE 语句的子查询只使用临时表。

只是为了展示概念,未测试:

SELECT DISTINCT 
     b.id
    INTO #TempRowsToKeep
    FROM 
     creature_template a inner join creature b on a.entry = b.id 
    WHERE 
     b.map != 571 
     AND (a.`type` = 1 or a.`type` = 10);

DELETE FROM 
     creature 
    WHERE 
     id not in 
      (SELECT id FROM #TempRowsToKeep);

DROP TABLE #TempRowsToKeep;

我不是 MySQl 专家,但如果 Mike 回答的解决方案有效,我认为你应该选择那个,因为它不涉及临时表,它只是一个语句而不是 3。事实上,当你试过了,它删除了你所有的行,这表明你在最里面的查询中的条件没有选择任何行,正如他所提到的。事实上,其中有一个错误,肯定会导致:

AND a.`type` = 1 AND a.`type` = 10

永远是假的。应该是

AND (a.`type` = 1 or a.`type` = 10)

我上面的代码包含这个更正,如果你使用它,请先仔细检查它。

【讨论】:

  • 您是否有“在 DELETE 语句的子查询的 WHERE 中使用临时表”的代码示例。部分?
  • @NZoth 查看我的编辑。无论如何,作为一般建议,不要让您恢复不情愿地删除的行是“幸运的”;要么按照 Mike 的评论建议先使用 SELECT 测试 DELETE 条件,或者在每次尝试之前系统地进行备份。
【解决方案2】:

使用“命名子查询破解”:

 DELETE FROM 
     creature 
    WHERE 
     id not in 
    (
     SELECT id FROM
      (
       SELECT DISTINCT b.id 
         FROM creature_template a inner join creature b on a.entry = b.id 
        WHERE b.map != 571 AND a.`type` = 1 AND a.`type` = 10
      ) A
    );

【讨论】:

  • 不。我刚刚尝试了您的解决方案,它删除了“生物”表中的所有数据。 :/ 幸运的是我有备份
  • @NZoth 您的情况可能没有选择任何记录。而id not in() 全选删除。首先将任何删除查询测试为选择。
猜你喜欢
  • 2013-07-05
  • 2012-12-03
  • 1970-01-01
  • 2016-05-19
  • 2012-03-06
  • 2015-06-08
  • 2015-07-11
  • 2016-08-25
  • 1970-01-01
相关资源
最近更新 更多