【问题标题】:Error on Trigger Syntax using IF-THEN-ELSE使用 IF-THEN-ELSE 触发语法错误
【发布时间】:2020-03-15 03:00:26
【问题描述】:

我有四张桌子

  • Processor_products 与列 NameSocket
  • Motherboard 与列 NameSocket
  • Build 与列 Processor(引用 Processor_products(Name)] 和 Motherboard [引用 Motherboard(Name)]
  • Compatibility 与列 compatibleid

如果插入到 Build 中的处理器和主板具有不同的 Socket,我想编写在 Compatibilty.compatible 中插入“No”的触发器,或者如果它们具有相同的 Socket,则插入“Yes”。

CREATE TRIGGER compatibility
AFTER INSERT ON build
BEGIN
IF ((SELECT * FROM build WHERE ORDER BY ID DESC LIMIT 1) EXISTS (SELECT * FROM processor_products pp, motherboard m where pp.Socket <> m.Socket))
THEN
INSERT INTO compatibility(compatibility) VALUE('no');
ELSE
INSERT INTO compatibility(compatibility) VALUE('yes');
END IF;
END

我正在使用 phpmyadmin,错误是我的语法错误。

1064 - 您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以获取在“BEGIN”附近使用的正确语法 IF ((SELECT * FROM build WHERE ORDER BY ID DESC LIMIT 1) EXISTS (SELECT *' at line 3

有人可以帮我吗?

表格:

Build table = https://i.stack.imgur.com/wxviV.png
Motherboard = https://i.stack.imgur.com/7YNAo.png
Processors = https://i.stack.imgur.com/HOVjU.png

【问题讨论】:

  • 乍一看,感觉/接缝就像丢失了DELIMITER,但没有检查其他语法错误或不合逻辑的错误..
  • 非常确定 phpmyadmin(正确的是 mysql)告诉您错误是什么...想与我们分享错误信息吗?
  • 添加后仍然出现语法错误。我已经用错误消息编辑了我的问题。
  • " 添加后我仍然遇到语法错误。我已经用错误消息编辑了我的问题。" 简而言之,触发代码是一团糟FOR EACH ROW 接缝是缺少 .. 还使用了 SELECT * FROM build WHERE ORDER BY 而没有有效的 WHERE 条件 .. 就像我说的,我没有检查其他语法问题
  • .. 另请参阅Why should I provide a Minimal Reproducible Example for a very simple SQL query?,因为您的触发代码取决于现有的表和数据..

标签: mysql mariadb


【解决方案1】:

无需深入研究语法的众多问题;并且没有深入研究触发器旨在解决的实际问题;把所有的讨论放在一边。

看起来触发器正在尝试:从motherboardprocessor 表的相关行中检索“socket”列的值,然后比较这两个字符串值,然后执行一些其他操作根据比较结果采取行动。


注意:

不要使用ORDER BY ... DESC LIMIT 1 来标识刚刚插入的行。

在 AFTER INSERT 触发器的主体中,我们可以通过使用 NEW 关键字限定列名来引用刚刚插入的行的值。

例如,在触发器中,对NEW.motherboardNEW.processor 的引用将分别返回刚刚插入的行的motherboardprocessor 列的值(由导致触发器被触发。)


这里演示了我们可能会编写一个执行这些操作的 AFTER INSERT 触发器的方法:

DELIMITER $$

CREATE TRIGGER `trg_build_ai`
AFTER INSERT ON `build`
FOR EACH ROW
BEGIN

    -- local variables
    DECLARE ls_compatiblity VARCHAR(4)    DEFAULT NULL;
    DECLARE ls_p_socket     VARCHAR(1024) DEFAULT NULL;
    DECLARE ls_m_socket     VARCHAR(1024) DEFAULT NULL;

    -- get "socket" values from motherboard and processor
    SELECT m.socket AS m_socket
         , p.socket AS p_socket
      FROM ( SELECT 1 AS n ) i
      LEFT
      JOIN ( -- retrieve related motherboard "socket" value
             SELECT ms.socket
               FROM motherboard ms
              WHERE ms.name   = NEW.motherboard
              ORDER BY ms.name, ms.socket
              LIMIT 1
           ) m
      LEFT
      JOIN ( -- retrieve related processor "socket" value
             SELECT ps.socket
               FROM processor_product ps
              WHERE ps.name   = NEW.processor
              ORDER BY ps.name, ps.socket
              LIMIT 1
           ) p
      INTO ls_m_socket
         , ls_p_socket
    ;

    -- check if values are equal
    IF ( ls_m_socket = ls_p_socket ) THEN
       SET ls_compatibility := 'yes'; 
    ELSE
       SET ls_compatibility := 'no';
    END IF;

    -- (not even going to try to fathom why we need to INSERT into another table)
    INSERT INTO `compatibility` ( `compatibility` ) VALUES ( ls_compatibility );

 END$$

 DELIMITER ;

【讨论】:

    猜你喜欢
    • 2016-02-27
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    • 2017-07-15
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多