简体   繁体   中英

Use ResultSet of SELECT...FOR UPDATE in MySQL Stored Procedure

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM