我有一个触发器,我希望有一个变量来保存我从 a 获得的 INT SELECT
,所以我可以在两个 IF 语句中使用它,而不是调用SELECT
两次。您如何在 MySQL 触发器中声明/使用变量?
Ice
问问题
183817 次
6 回答
56
DECLARE
您可以使用语法在 MySQL 触发器中声明局部变量。
这是一个例子:
DROP TABLE IF EXISTS foo;
CREATE TABLE FOO (
i SERIAL PRIMARY KEY
);
DELIMITER //
DROP TRIGGER IF EXISTS bar //
CREATE TRIGGER bar AFTER INSERT ON foo
FOR EACH ROW BEGIN
DECLARE x INT;
SET x = NEW.i;
SET @a = x; -- set user variable outside trigger
END//
DELIMITER ;
SET @a = 0;
SELECT @a; -- returns 0
INSERT INTO foo () VALUES ();
SELECT @a; -- returns 1, the value it got during the trigger
为变量赋值时,必须确保查询只返回一个值,而不是一组行或一组列。例如,如果您的查询在实践中返回一个值,那没关系,但只要它返回多行,您就会得到“ ERROR 1242: Subquery returns more than 1 row
”。
您可以使用LIMIT
orMAX()
来确保将局部变量设置为单个值。
CREATE TRIGGER bar AFTER INSERT ON foo
FOR EACH ROW BEGIN
DECLARE x INT;
SET x = (SELECT age FROM users WHERE name = 'Bill');
-- ERROR 1242 if more than one row with 'Bill'
END//
CREATE TRIGGER bar AFTER INSERT ON foo
FOR EACH ROW BEGIN
DECLARE x INT;
SET x = (SELECT MAX(age) FROM users WHERE name = 'Bill');
-- OK even when more than one row with 'Bill'
END//
于 2008-11-29T23:29:15.373 回答
7
`CREATE TRIGGER `category_before_ins_tr` BEFORE INSERT ON `category`
FOR EACH ROW
BEGIN
**SET @tableId= (SELECT id FROM dummy LIMIT 1);**
END;`;
于 2008-11-27T21:58:54.337 回答
7
CREATE TRIGGER clearcamcdr AFTER INSERT ON `asteriskcdrdb`.`cdr`
FOR EACH ROW
BEGIN
SET @INC = (SELECT sip_inc FROM trunks LIMIT 1);
IF NEW.billsec >1 AND NEW.channel LIKE @INC
AND NEW.dstchannel NOT LIKE ""
THEN
insert into `asteriskcdrdb`.`filtre` (id_appel,date_appel,source,destinataire,duree,sens,commentaire,suivi)
values (NEW.id,NEW.calldate,NEW.src,NEW.dstchannel,NEW.billsec,"entrant","","");
END IF;
END$$
不要尝试这个@home
于 2009-05-15T12:43:45.717 回答
4
我发布这个解决方案是因为我很难找到我需要的东西。这篇文章让我足够接近(+1 表示感谢),如果数据与 test 匹配,这是插入之前重新排列列数据的最终解决方案。
注意:这是来自我继承的遗留项目,其中:
- 唯一键是
rridprefix
+rrid
- 在我接手之前,没有任何约束可以防止重复的唯一键
- 我们需要将两个表(一个充满重复项)组合到主表中,该表现在对复合键有约束(因此合并失败,因为获取表不允许来自不干净表的重复项)
on duplicate key
不太理想,因为列太多并且可能会更改
无论如何,这里的触发器将任何重复的键放入遗留列,同时允许我们存储遗留的坏数据(而不是触发获取表的复合唯一键)。
BEGIN
-- prevent duplicate composite keys when merging in archive to main
SET @EXIST_COMPOSITE_KEY = (SELECT count(*) FROM patientrecords where rridprefix = NEW.rridprefix and rrid = NEW.rrid);
-- if the composite key to be introduced during merge exists, rearrange the data for insert
IF @EXIST_COMPOSITE_KEY > 0
THEN
-- set the incoming column data this way (if composite key exists)
-- the legacy duplicate rrid field will help us keep the bad data
SET NEW.legacyduperrid = NEW.rrid;
-- allow the following block to set the new rrid appropriately
SET NEW.rrid = null;
END IF;
-- legacy code tried set the rrid (race condition), now the db does it
SET NEW.rrid = (
SELECT if(NEW.rrid is null and NEW.legacyduperrid is null, IFNULL(MAX(rrid), 0) + 1, NEW.rrid)
FROM patientrecords
WHERE rridprefix = NEW.rridprefix
);
END
于 2016-12-20T15:42:55.467 回答
2
或者您可以只在调用触发器的 SQL 中包含 SELECT 语句,因此它作为触发器行中的列之一传入。只要您确定它只会返回一行(因此只有一个值)。(当然,它不能返回与触发器中的逻辑交互的值,但无论如何都是如此。)
于 2008-11-27T23:29:27.103 回答
1
据我想我理解你的问题我相信你可以简单地在“DECLARE”中声明你的变量,然后在“开始”之后你可以使用'select into'you variable''语句。代码如下所示:
DECLARE
YourVar varchar(50);
begin
select ID into YourVar from table
where ...
于 2020-07-01T07:34:16.570 回答