I'm using MySql 5.7 trying to create a stored procedure that will update a set of rows in a transaction and return the rows that were updated. After creating the locks, I then update those rows, but can't figure out how to use the ids returned from the SELECT...FOR UPDATE
statement. Instead I have to scan the table again in the update statement looking for the rows I just locked. Here's an example of my procedure.
DELIMITER //
CREATE PROCEDURE cleanUp()
BEGIN
START TRANSACTION;
SELECT * FROM t WHERE t.state = 'foobar' AND t.value < 10 FOR UPDATE;
UPDATE t SET t.state = 'fizzbuzz' WHERE t.state = 'foobar' AND t.value < 10;
COMMIT;
END //
I'd prefer to not have to scan the table twice for t.state = 'foobar' AND t.value < 10
. I'd also like to guarantee that I only update the rows I just locked, not other rows that might have been changed to meet that criteria mid-transaction.
Is there a way to use the results of SELECT..FOR UPDATE
in the UPDATE
statement so I can update rows by id instead?
Note: I've tried loading the results into a temp table and using a cursor and both do not work.
MySQL can't declared variable as table, so you need o write the select in a FROM clause, which can for example do as IN clause like the query below
CREATE TABLe t(id int, state varchar(10), value int)
INSERT INTO t VALUEs(1,'foobar',1),(2,'foobar',1),(3,'foobar',1)
CREATE PROCEDURE cleanUp() BEGIN START TRANSACTION; UPDATE t SET t.state = 'fizzbuzz' WHERE id IN (SELECT id FROM (SELECT id FROM t WHERE t.state = 'foobar' AND t.value < 10 FOR UPDATE) t1 ); COMMIT; END
CALL cleanUp()
SELECT * FROM t
id | state | value -: |:------- | ----: 1 | fizzbuzz | 1 2 | fizzbuzz | 1 3 | fizzbuzz | 1
db<>fiddle here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.