source

MySQL 트리거 - 변수에 SELECT 저장

gigabyte 2022. 9. 18. 10:13
반응형

MySQL 트리거 - 변수에 SELECT 저장

트리거가 있는데, 이 트리거에서 얻은 INT를 보유하는 변수를 사용하고 싶다.SELECT그래서 2개의 IF 스테이트먼트에서 사용할 수 있습니다.SELECT두 번. MySQL 트리거에서 변수를 선언/사용하려면 어떻게 해야 합니까?

MySQL 트리거에서 로컬 변수를 선언하려면DECLARE구문을 사용합니다.

다음은 예를 제시하겠습니다.

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또는MAX()로컬 변수가 단일 값으로 설정되었는지 확인합니다.

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//
`CREATE TRIGGER `category_before_ins_tr` BEFORE INSERT ON `category`
  FOR EACH ROW
BEGIN
    **SET @tableId= (SELECT id FROM dummy LIMIT 1);**

END;`;
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$$

@ 홈에서 시도하지 마세요.

필요한 것을 찾기가 어려워서 이 해결책을 올렸습니다.이 투고에서는 (+1)에 충분히 가까워졌습니다.데이터가 테스트와 일치하는 경우 컬럼 데이터를 삽입하기 전에 재배치하기 위한 최종 솔루션을 소개합니다.

주의: 이것은 제가 상속받은 레거시 프로젝트에서 가져온 것입니다.

  1. Unique Key는 다음 컴포지트입니다.rridprefix+rrid
  2. 내가 인수하기 전에는 중복되는 고유 키를 막는 제약이 없었다.
  3. 2개의 테이블(중복으로 가득 찬 것)을 메인 테이블로 결합할 필요가 있었습니다.메인 테이블은 현재 컴포지트 키에 제약이 있습니다(따라서 취득 테이블은 부정한 테이블로부터의 복제를 허용하지 않기 때문에 Marge는 실패합니다).
  4. 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

또는 트리거를 호출하는 SQL에 SELECT 문을 포함하면 트리거 행의 열 중 하나로 전달됩니다.확실한 한 반드시 한 행만 반환됩니다(따라서 한 개의 값만 반환됩니다.(물론 트리거 내의 로직과 상호작용하는 값을 반환해서는 안 되지만, 어떤 경우에도 해당됩니다).

질문을 이해한 이상, "DECARE" 내에서 변수를 선언하고 "begin" 후에 "select into "you variable" 스테이트먼트를 사용할 수 있다고 생각합니다.코드는 다음과 같습니다.

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

언급URL : https://stackoverflow.com/questions/324605/mysql-trigger-storing-a-select-in-a-variable

반응형