MySQL 在插入后触发器错误中删除行
MySQL Deleting Row in an After Insert Trigger Error
我在 MySQL 数据库中有三个 table,bids
、offers
和 matched
。 matched
table 包含已匹配的出价和报价。有一个事件运行逻辑来执行下面显示的匹配。
CREATE EVENT bid_offer_matching
ON SCHEDULE EVERY 1 SECOND
STARTS CURRENT_TIMESTAMP
DO
INSERT INTO Matched(
consumer_id, /* Bidder */
producer_id, /* Offer */
bid_id, /* bid id */
offer_id, /* offer id */
volume, /* Volume */
price, /* Price */
market_time) /* Market Time */
SELECT
bids.user_id, /* Bidder */
offers.user_id, /* Offer */
bids.bid_id, /* Bid ID */
offers.offer_id, /* Offer ID */
bids.bid_volume, /* Volume */
bids.bid_price, /* Price */
bids.market_time /* Market Time */
FROM
Bids bids
INNER JOIN (
SELECT *, ROW_NUMBER()
OVER (
PARTITION BY
offer_volume /* Partition by the volume in the offer */
ORDER BY
/* Order each partiton by the price low to high, this makes row 1 in each partition the lowest price offer*/
offer_price
)rn /* Get the row number also back */
FROM Offers
) offers
ON
/* Volume must be equal */
bids.bid_volume = offers.offer_volume AND
/*Price must be at least asking price */
bids.bid_price >= offers.offer_volume AND
/* Market time must be same */
bids.market_time >= offers.market_time
WHERE
/* This is important, it matches only the above condition to the lowest offer price resulting in best price for bidder */
offers.rn = 1;
当我在 matched
table 上创建触发器以删除从 bids
和 offers
table 中插入的出价和报价时出现问题.我想删除它们,因为它们一旦匹配就不再需要了。此触发器的逻辑如下所示。
/*Crete the trigger*/
DELIMITER $$
CREATE TRIGGER match_insert_trigger
AFTER INSERT
ON Matched FOR EACH ROW
BEGIN
/* DELETE THE BID*/
DELETE FROM
Bids
WHERE
bid_id=NEW.bid_id; /* The bid ID is inserted into the matched table to be used as reference, not a foreign key though */
/* DELETE THE OFFER */
DELETE FROM
Offers
WHERE
offer_id=NEW.offer_id; /* The offer ID is inserted into the matched table to be used as reference, not a foreign key though */
END$$
DELIMITER ;
但是,当尝试执行事件以匹配出价和报价时,现在会发生错误
Error Code: 1442. Can't update table 'Bids' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
我只是在 match_insert_trigger
事件中更新 Bids
table,但出价 table 并未用于触发任何事情,所以有点不确定这里出了什么问题?
编辑
我通过放置删除事件 bid_offer_matching
中匹配的 bids/offers 的逻辑实现了我需要的功能。
但是我仍然不明白上面的错误是怎么发生的,如果有人知道的话。
下面是新的活动代码
DELIMITER $$
CREATE EVENT bid_offer_matching
ON SCHEDULE EVERY 1 SECOND
STARTS CURRENT_TIMESTAMP
DO
BEGIN
INSERT INTO Matched(
consumer_id, /* Bidder */
producer_id, /* Offer */
bid_id, /* bid id */
offer_id, /* offer id */
volume, /* Volume */
price, /* Price */
market_time) /* Market Time */
SELECT
bids.user_id, /* Bidder */
offers.user_id, /* Offer */
bids.bid_id, /* Bid ID */
offers.offer_id, /* Offer ID */
bids.bid_volume, /* Volume */
bids.bid_price, /* Price */
bids.market_time /* Market Time */
FROM
Bids bids
INNER JOIN (
SELECT *, ROW_NUMBER()
OVER (
PARTITION BY
offer_volume /* Partition by the volume in the offer */
ORDER BY
/* Order each partiton by the price low to high, this makes row 1 in each partition the lowest price offer*/
offer_price
)rn /* Get the row number also back */
FROM Offers
) offers
ON
/* Volume must be equal */
bids.bid_volume = offers.offer_volume AND
/*Price must be at least asking price */
bids.bid_price >= offers.offer_volume AND
/* Market time must be same */
bids.market_time >= offers.market_time
WHERE
/* This is important, it matches only the above condition to the lowest offer price resulting in best price for bidder */
offers.rn = 1;
/* *****DELETE STATEMENT ***** */
/* DELETE THE OFFERS */
DELETE FROM
Offers
WHERE
offer_id
IN
(SELECT offer_id FROM Matched);
/* DELETE THE BIDS */
DELETE FROM
Bids
WHERE
bid_id
IN
(SELECT bid_id FROM Matched);
END$$
DELIMITER ;
您的事件主体中的代码执行 INSERT INTO Matched... SELECT ... FROM Bids...
https://dev.mysql.com/doc/refman/8.0/en/stored-program-restrictions.html 说:
A stored function or trigger cannot modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
请注意它说 “用于阅读或写作”。 这意味着通过 阅读 来自 table 的投标 table在你的 INSERT...SELECT
语句中做的,这与你不能修改触发器中的 tables 的规则冲突,这些触发器正在调用触发器的语句中读取。
我在 MySQL 数据库中有三个 table,bids
、offers
和 matched
。 matched
table 包含已匹配的出价和报价。有一个事件运行逻辑来执行下面显示的匹配。
CREATE EVENT bid_offer_matching
ON SCHEDULE EVERY 1 SECOND
STARTS CURRENT_TIMESTAMP
DO
INSERT INTO Matched(
consumer_id, /* Bidder */
producer_id, /* Offer */
bid_id, /* bid id */
offer_id, /* offer id */
volume, /* Volume */
price, /* Price */
market_time) /* Market Time */
SELECT
bids.user_id, /* Bidder */
offers.user_id, /* Offer */
bids.bid_id, /* Bid ID */
offers.offer_id, /* Offer ID */
bids.bid_volume, /* Volume */
bids.bid_price, /* Price */
bids.market_time /* Market Time */
FROM
Bids bids
INNER JOIN (
SELECT *, ROW_NUMBER()
OVER (
PARTITION BY
offer_volume /* Partition by the volume in the offer */
ORDER BY
/* Order each partiton by the price low to high, this makes row 1 in each partition the lowest price offer*/
offer_price
)rn /* Get the row number also back */
FROM Offers
) offers
ON
/* Volume must be equal */
bids.bid_volume = offers.offer_volume AND
/*Price must be at least asking price */
bids.bid_price >= offers.offer_volume AND
/* Market time must be same */
bids.market_time >= offers.market_time
WHERE
/* This is important, it matches only the above condition to the lowest offer price resulting in best price for bidder */
offers.rn = 1;
当我在 matched
table 上创建触发器以删除从 bids
和 offers
table 中插入的出价和报价时出现问题.我想删除它们,因为它们一旦匹配就不再需要了。此触发器的逻辑如下所示。
/*Crete the trigger*/
DELIMITER $$
CREATE TRIGGER match_insert_trigger
AFTER INSERT
ON Matched FOR EACH ROW
BEGIN
/* DELETE THE BID*/
DELETE FROM
Bids
WHERE
bid_id=NEW.bid_id; /* The bid ID is inserted into the matched table to be used as reference, not a foreign key though */
/* DELETE THE OFFER */
DELETE FROM
Offers
WHERE
offer_id=NEW.offer_id; /* The offer ID is inserted into the matched table to be used as reference, not a foreign key though */
END$$
DELIMITER ;
但是,当尝试执行事件以匹配出价和报价时,现在会发生错误
Error Code: 1442. Can't update table 'Bids' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
我只是在 match_insert_trigger
事件中更新 Bids
table,但出价 table 并未用于触发任何事情,所以有点不确定这里出了什么问题?
编辑
我通过放置删除事件 bid_offer_matching
中匹配的 bids/offers 的逻辑实现了我需要的功能。
但是我仍然不明白上面的错误是怎么发生的,如果有人知道的话。
下面是新的活动代码
DELIMITER $$
CREATE EVENT bid_offer_matching
ON SCHEDULE EVERY 1 SECOND
STARTS CURRENT_TIMESTAMP
DO
BEGIN
INSERT INTO Matched(
consumer_id, /* Bidder */
producer_id, /* Offer */
bid_id, /* bid id */
offer_id, /* offer id */
volume, /* Volume */
price, /* Price */
market_time) /* Market Time */
SELECT
bids.user_id, /* Bidder */
offers.user_id, /* Offer */
bids.bid_id, /* Bid ID */
offers.offer_id, /* Offer ID */
bids.bid_volume, /* Volume */
bids.bid_price, /* Price */
bids.market_time /* Market Time */
FROM
Bids bids
INNER JOIN (
SELECT *, ROW_NUMBER()
OVER (
PARTITION BY
offer_volume /* Partition by the volume in the offer */
ORDER BY
/* Order each partiton by the price low to high, this makes row 1 in each partition the lowest price offer*/
offer_price
)rn /* Get the row number also back */
FROM Offers
) offers
ON
/* Volume must be equal */
bids.bid_volume = offers.offer_volume AND
/*Price must be at least asking price */
bids.bid_price >= offers.offer_volume AND
/* Market time must be same */
bids.market_time >= offers.market_time
WHERE
/* This is important, it matches only the above condition to the lowest offer price resulting in best price for bidder */
offers.rn = 1;
/* *****DELETE STATEMENT ***** */
/* DELETE THE OFFERS */
DELETE FROM
Offers
WHERE
offer_id
IN
(SELECT offer_id FROM Matched);
/* DELETE THE BIDS */
DELETE FROM
Bids
WHERE
bid_id
IN
(SELECT bid_id FROM Matched);
END$$
DELIMITER ;
您的事件主体中的代码执行 INSERT INTO Matched... SELECT ... FROM Bids...
https://dev.mysql.com/doc/refman/8.0/en/stored-program-restrictions.html 说:
A stored function or trigger cannot modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
请注意它说 “用于阅读或写作”。 这意味着通过 阅读 来自 table 的投标 table在你的 INSERT...SELECT
语句中做的,这与你不能修改触发器中的 tables 的规则冲突,这些触发器正在调用触发器的语句中读取。