【问题标题】:Get result from prepared query in a MySQL Trigger?从 MySQL 触发器中的准备查询中获取结果?
【发布时间】:2014-01-09 22:32:11
【问题描述】:

您好,我对 MySQL 触发器很陌生。我想从准备好的查询中获取结果,但看不到如何使以下代码正常工作:

BEGIN
    DECLARE un_quer varchar(255);
    DECLARE res integer;

    IF(NEW.contact_id IS NULL) THEN
        IF(NEW.name IS NULL OR NEW.email IS NULL) THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Forbidden: ... information not sufficient.';
        END IF;
    END IF;

    IF(NEW.name IS NULL OR NEW.email IS NULL) THEN
        IF(NEW.contact_id IS NULL) THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Forbidden: ... information not sufficient.';
        END IF;
    END IF;

    SET un_quer = CONCAT('SELECT COUNT(*) FROM tender_tenderer WHERE tender_id=',NEW.tender_id);

    IF(NEW.contact_id IS NULL) THEN
        SET un_quer = CONCAT(un_quer,' AND contact_id IS NULL');
    ELSE
        SET un_quer = CONCAT(un_quer,' AND contact_id = ',NEW.contact_id);
    END IF;

    IF(NEW.name IS NULL) THEN
        SET un_quer = CONCAT(un_quer,' AND name IS NULL');
    ELSE
        SET un_quer = CONCAT(un_quer,' AND name = "',NEW.name,'"');
    END IF;

    PREPARE stmt1 FROM un_quer;

    SET res = (EXECUTE stmt1);


    IF (0 < res) THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Forbidden: ...';
    END IF;
END

我认为大部分代码都有效,但“SET res = (EXECUTE stmt1);”行会产生错误。如何将 stmt1 的结果选择到变量 $res 中,以便在 IF 子句中使用结果整数进行比较?

注意:基本问题是我想在 Mysql InnoDB 中有一个“唯一约束”,它适用于 NULL 值。

【问题讨论】:

    标签: mysql sql triggers


    【解决方案1】:

    您不能SET 对变量的查询结果,即使此查询仅返回一个值。将b.b3rn4rd's 语法与queries returning one single row 一起使用。 (仅供参考,需要使用CURSOR 来迭代包含多行的查询结果)

    不过这里不需要prepared statement,可以使用null-safe comparison operator:

    SELECT COUNT(*) INTO res
    FROM tender_tenderer
    WHERE tender_id = NEW.tender_id
    AND contact_id <=> NEW.contact_id
    AND name <=> NEW.name;
    
    IF (0 < res) THEN
    ...
    

    【讨论】:

    • 顺便说一下,你的前两个IF() 是严格等价的:o)
    【解决方案2】:

    使用INTO 语句。

    SET un_quer = CONCAT('SELECT COUNT(*) INTO res FROM tender_tenderer WHERE tender_id=',NEW.tender_id);
    ...
    EXECUTE stmt1;
    

    【讨论】:

    • 也感谢您的回答,它是正确的。然而 RandomSeed 的答案是我现在实际解决它的方式。
    猜你喜欢
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 2017-04-25
    • 2019-01-02
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多