I have three tables in a MySQL database, bids
, offers
and matched
. The matched
table contains bids and offers which have been matched. There is an event that runs the logic to do the matching shown below which works.
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;
The problem occurs when I create a trigger on the matched
table to delete the bid and offer inserted from the bids
and offers
table. I want to delete them as they are no longer needed once they are matched. The logic for this trigger is shown below.
/*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 ;
The error now occurs however when trying to execute the event to match bids and offers
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.
I am only updating the Bids
table in the event match_insert_trigger
but the bids table is not used to trigger anything so bit unsure what is wrong here?
EDIT
I have achieved the functionality I need by placing the logic to delete the matched bids/offers in the event bid_offer_matching
.
However I still do not understand how the above error is occurring if anyone knows.
New event code below
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 ;