gpt4 book ai didi

在同一个表上插入时的 MySQL 触发器不起作用

转载 作者:可可西里 更新时间:2023-11-01 08:44:57 25 4
gpt4 key购买 nike

上周在 SO 和许多其他网站上度过之后,我还有两个案例仍​​然无法正确编写触发器/函数等。这是我第一次在真实项目中使用触发器。

这是此示例的示例表。我正在处理像 scenerio 这样的报价代码。

CREATE TABLE IF NOT EXISTS `Demo` (
`id` int(100) unsigned NOT NULL AUTO_INCREMENT,
`Code` varchar(25) NOT NULL,
`StoreID` int(100) unsigned NOT NULL,
`EndsOn` date DEFAULT NULL,
`Status` enum('Active','Inactive') NOT NULL DEFAULT 'Active',
PRIMARY KEY (`id`)

);

案例一:
一个code+storeid就是一个offer。只能有一个具有相同 Code+StoreID 的有效报价。因此,我无法在 Code+Storeid+Status 上设置复合唯一键,因为对非事件商品没有限制。我只需要确保不会出现重复的有效报价。目前我在 PHP 中使用 1 个用于检查的转换和另一个用于插入的转换。
我尝试在插入之前创建一个触发器,但事实证明我无法在触发器正在作用的同一个表上插入。

CREATE TRIGGER `trig_no_dup` BEFORE INSERT ON `Demo` FOR EACH ROW
BEGIN
SET @Counter = (SELECT COUNT(*) FROM `Demo` WHERE `StoreID` = NEW.StoreID AND `Code` = NEW.Code AND `Status` = 'Active');
IF @Counter = 0 THEN
INSERT INTO Demo (Code, StoreID) values (NEW.Code,NEW.StoreID);
ELSE
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='Hello, world! From Else Block';
END IF;
END;

然后我创建了一个函数(因为存储过程不返回消息)但它不起作用,它总是进入 if 子句,从不进入 else 子句。

CREATE FUNCTION `func_no_dup` (l_Code varchar(25), l_StoreID int(100) ) RETURNS varchar(255)
BEGIN
SET @Counter = (SELECT COUNT(*) FROM `Demo` WHERE `StoreID` = l_StoreID AND `Code` = l_StoreID AND `Status` = 'Active');
IF @Counter = 0 THEN
RETURN 'OFFER DOES NOT EXISTS YET!!!!';
ELSE
RETURN 'Offer is already active';
END IF;
END;

如何从数据库中对此场景实现插入前检查?

案例二
我正在尝试创建一个事件触发器,它将优惠券的状态设置为 Inactive 对于那些结束日期到期的优惠券。我尝试了一个教程 http://www.sitepoint.com/how-to-create-mysql-events/ ,但无法使其正常工作。我通过使用 PDO 在简单的 sql 准备语句中使用 FROM_UNIXTIME(:EndsOn) 来保存数据库中的条目,并且 $Coupon[":EndsOn"] = $dateFactory->today()-> addWeeks(4)->getTimestamp(); $dateFactory 是 Carbon 库的对象,它是 PHP DateTime 类的扩展。

任何人都可以给我代码或伪代码示例吗?

最佳答案

对于情况 1,如果重复检测没有找到任何重复项,您不应该执行插入操作,正常的插入操作会执行此操作

CREATE TRIGGER `trig_no_dup` BEFORE INSERT ON `Demo` FOR EACH ROW
BEGIN
SET @Counter = (SELECT COUNT(*) FROM `Demo` WHERE `StoreID` = NEW.StoreID AND `Code` = NEW.Code AND `Status` = 'Active');
-- if @Counter is 0 then just don't signal an error
IF @Counter != 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='Hello, world! From Else Block';
END IF;
END;

对于情况 2,我认为这可行

CREATE EVENT deleteOld 
ON SCHEDULE EVERY HOUR
DO UPDATE demo SET status = 'Inactive' WHERE EndsOn < NOW();

确保在 EndsOn 上有一个索引,这会很快。

关于在同一个表上插入时的 MySQL 触发器不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31512034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com