MySQL触发器 - 将SELECT存储在变量中

时间:2008-11-27 20:33:00

标签: mysql sql triggers

我有一个触发器,我希望有一个变量来保存我从SELECT获得的INT,所以我可以在两个IF语句中使用它,而不是两次调用SELECT。如何在MySQL触发器中声明/使用变量?

6 个答案:

答案 0 :(得分:49)

您可以使用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”。

您可以使用LIMITMAX()来确保将局部变量设置为单个值。

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//

答案 1 :(得分:7)

`CREATE TRIGGER `category_before_ins_tr` BEFORE INSERT ON `category`
  FOR EACH ROW
BEGIN
    **SET @tableId= (SELECT id FROM dummy LIMIT 1);**

END;`;

答案 2 :(得分:6)

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

答案 3 :(得分:2)

或者您可以在调用触发器的SQL中包含SELECT语句,因此它作为触发器行中的一个列传入。只要你确定它将无可置疑地只返回一行(因此一个值)。 (当然,它不能返回与触发器中的逻辑交互的值,但在任何情况下都是如此。)

答案 4 :(得分:1)

到目前为止,我认为我理解了您的问题 我相信您可以在“ DECLARE”中声明您的变量 然后在“开始”之后,您可以使用“选择进入”您的变量”语句。 代码如下:

DECLARE
YourVar  varchar(50);
begin 
select ID into YourVar  from table
where ...

答案 5 :(得分:0)

我发布此解决方案是因为我很难找到我需要的东西。这篇文章让我足够接近(感谢+1),如果数据匹配测试,这是在插入之前重新排列列数据的最终解决方案。

注意:这是来自遗留项目我继承的地方:

  1. 唯一键是rridprefix + rrid
  2. 的组合
  3. 在我接手之前,没有任何约束阻止重复的唯一键
  4. 我们需要将两个表(一个完整的重复项)组合到主表中,该表现在对复合键有约束(因此合并失败,因为获取表不会允许来自不干净表的重复项)< / LI>
  5. on duplicate key不太理想,因为列太多且可能会更改
  6. 无论如何,这里是将任何重复密钥放入旧版列的触发器,同时允许我们存储遗留的坏数据(而不是触发获取表复合,唯一密钥)

    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