错误1093:MySQL无法在FROM子句中指定要更新的目标表

时间:2013-02-02 17:40:38

标签: mysql sql triggers mysql-workbench mysql-error-1093

error 1093: MySQL can’t specify target table 'SENTIERO' for update in FROM clause

这是我的触发器:

CREATE TRIGGER lunghezza_sentiero_datoderivato_INSERT
AFTER INSERT ON SENTIERO_HA_TAPPA
FOR EACH ROW

BEGIN

UPDATE SENTIERO
SET lunghezza= (SELECT SUM(lunghezza)
                FROM TAPPA, SENTIERO as S2, SENTIERO_HA_TAPPA
                WHERE NEW.IDsentiero=S2.IDsentiero
                and SENTIERO_HA_TAPPA.IDtappa=TAPPA.IDtappa);
WHERE IDsentiero IN (SELECT IDsentiero
                     FROM TAPPA, SENTIERO, SENTIERO_HA_TAPPA
                     WHERE SENTIERO_HA_TAPPA.IDsentiero=SENTIERO.IDsentiero
                     and NEW.IDtappa=SENTIERO_HA_TAPPA.IDtappa);
END$$

我发现这篇文章关于这个问题,请检查一下 http://verysimple.com/2011/03/30/mysql-cant-specify-target-table-for-update-in-from-clause/

这是我唯一的机会吗? 请帮帮我

编辑::我刚刚添加了'WHERE'子句,但它标志着我“错误语法”......为什么?

1 个答案:

答案 0 :(得分:1)

请改为尝试:

UPDATE SENTIERO s
INNER JOIN
(
   SELECT IDsentiero, TheSum
   FROM
   (
      SELECT S2.IDsentiero, SUM(s2.lunghezza) AS TheSum
      FROM SENTIERO AS S2 
      INNER JOIN SENTIERO_HA_TAPPA AS st ON st.IDsentiero = S2.IDsentiero
      INNER JOIN TAPPA             AS  t ON st.IDtappa    = t.IDtappa
      GROUP BY S2.IDsentiero
   ) AS Sub
) AS s2 ON s.IDsentiero  = s2.IDsentiero 
SET s.lunghezza = s2.TheSum
WHERE S2.IDsentiero = NEW.IDsentiero;

更新

您必须从lunghezza表格中获取TAPPA的价值总和而不是SENTIERO,这就是您获得NULL值的原因。所以最终的CREATE TRIGGER代码应该是这样的:

CREATE TRIGGER lunghezza_sentiero_datoderivato_INSERT
AFTER INSERT ON SENTIERO_HA_TAPPA
FOR EACH ROW

BEGIN

  UPDATE SENTIERO s
  INNER JOIN
  (
     SELECT IDsentiero, TheSum
     FROM
     (
        SELECT S2.IDsentiero, SUM(t.lunghezza) AS TheSum
        FROM SENTIERO AS S2 
        INNER JOIN SENTIERO_HA_TAPPA AS st ON st.IDsentiero = S2.IDsentiero
        INNER JOIN TAPPA             AS  t ON st.IDtappa    = t.IDtappa
        GROUP BY S2.IDsentiero
     ) AS Sub
  ) AS s2 ON s.IDsentiero  = s2.IDsentiero 
  SET s.lunghezza = s2.TheSum;

END

SQL Fiddle Demo

请注意:当表格lunghezza 中插入任何行时,此触发器会更新表SENTIEROSENTIERO_HA_TAPPA的值代表IDsentiero中的所有SENTIERO ,而不仅仅是新插入的IDsentiero的值。

要仅将lunghezza的新插入值的IDsentiero值更新到表SENTIERO_HA_TAPPA中,请在WHERE S2.IDsentiero = NEW.IDsentiero语句中添加UPDATE触发器像这样:

CREATE TRIGGER lunghezza_sentiero_datoderivato_INSERT
AFTER INSERT ON SENTIERO_HA_TAPPA
FOR EACH ROW

BEGIN

  UPDATE SENTIERO s
  INNER JOIN
  (
     SELECT IDsentiero, TheSum
     FROM
     (
        SELECT S2.IDsentiero, SUM(t.lunghezza) AS TheSum
        FROM SENTIERO AS S2 
        INNER JOIN SENTIERO_HA_TAPPA AS st ON st.IDsentiero = S2.IDsentiero
        INNER JOIN TAPPA             AS  t ON st.IDtappa    = t.IDtappa
        GROUP BY S2.IDsentiero
     ) AS Sub
  ) AS s2 ON s.IDsentiero  = s2.IDsentiero 
  SET s.lunghezza = s2.TheSum
  WHERE S2.IDsentiero = NEW.IDsentiero;

END;

例如,如果创建三个表,则将数据插入表中,然后创建该触发器。然后像这样插入表SENTIERO_HA_TAPPA

INSERT INTO `SENTIERO_HA_TAPPA` (`IDtappa`, `IDsentiero`) VALUES (14, 4); 

然后触发器将仅在表IDsentiero = 4中更新SENTIERO的值,而不是其所有值。其他lunghezza的{​​{1}}值为IDsentiero s:

因此,您必须在插入之前创建表和触发器。然后插入表中,以便获得一致的数据。它应该如何运作。

如以下演示:


请注意: 在本回答的所有演示中,我只使用了触发器涉及的三个表,同时我修改了两个字段NULLinizio在表fine中可以为空,因为该表中的insert子句对这些列有TAPPA个值。