SELECT
から取得したINTを保持する変数が必要なトリガーがあるため、SELECT
を2回呼び出す代わりに、2つのIFステートメントで使用できます。 MySQLトリガーで変数をどのように宣言/使用しますか?
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
または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$$
これを@ homeにしないでください
または、トリガーを呼び出すSQLにSELECTステートメントを含めるだけで、トリガー行の列の1つとして渡すことができます。確実である限り、確実に1行のみを返します(したがって1つの値)。 (そしてもちろん、トリガーのロジックと相互作用する値を返すことはできませんが、それはいずれの場合にも当てはまります。)
必要なものを見つけるのに苦労したため、このソリューションを投稿しています。この投稿で私は十分に近くなりました(ありがとうございました+1)。これがデータがテストに一致する場合、挿入前に列データを再配置するの最終的な解決策です。
注:これはレガシープロジェクトからのものです。
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