I'm working on a application for which I need to read m
rows at a time out of total 'N' rows where m < N
. Every time I read 'm' rows I have to set their status as read
in the same table.
For example consider following table
+------+-------------------------+--------------------------+----------+-------+---------+------+
| ID | from_email_address | to_email_address | subject | body | inqueue | sent |
+------+-------------------------+--------------------------+----------+-------+---------+------+
| 1 | 0120sushil@gmail.com | kumar.sushil@outlook.com | Subject1 | Body1 | 0 | 0 |
| 2 | 0120ksushil@gmail.com | kumar.sushil@outlook.com | Subject1 | Body1 | 0 | 0 |
| 3 | shivaseth1@gmail.com | kumar.sushil@outlook.com | Subject1 | Body1 | 0 | 0 |
| 4 | shivaseth1@gmail.com | amanrajg@outlook.com | Subject1 | Body1 | 0 | 0 |
| 5 | shivamprakash@gmail.com | amanrajg@outlook.com | Subject1 | Body1 | 0 | 0 |
| 6 | shivamprakash@gmail.com | poorvanagpal@outlook.com | Subject1 | Body1 | 0 | 0 |
| 7 | shivankgupta@gmail.com | poorvanagpal@outlook.com | Subject1 | Body1 | 0 | 0 |
+------+-------------------------+--------------------------+----------+-------+---------+------+
I want to read lets say 3 rows
at a time and once I have read the rows I want to set inqueue
status of those rows as 1
.
I can use following query in stored procedure to select the rows
select * from EmailQueue where inqueue=1 LIMIT 3
After this how to update the same rows and set their inqueue
to 1
.
EDIT
Here is the stored procedure I created which is giving some error.
DELIMITER $$
DROP PROCEDURE IF EXISTS GetUnsentMails;
CREATE PROCEDURE GetUnsentMails()
BEGIN
START TRANSACTION;
CREATE TEMPORARY TABLE temp_EmailQueue AS SELECT * FROM EmailQueue WHERE inqueue = 0 LIMIT 5 FOR UPDATE;
UPDATE EmailQueue SET inqueue=1 where id in (SELECT id from temp_EmailQueue) AND inqueue = 0;
COMMIT;
END
It gives following error on calling
ERROR 1746 (HY000): Can't update table 'emailqueue' while 'temp_EmailQueue' is being created.
Suggesting to use Transaction and "SELECT FOR UPDATE" to fulfill your requirements.
Please refer following links for the examples:
MySQL 'select for update' behaviour
http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
http://www.sqlines.com/mysql/how-to/select-update-single-statement-race-condition
UPDATE - Added the QUERY EXAMPLE:
Example:
.......
#Before starting procedure
.......
START TRANSACTION;
CREATE TEMPORARY TABLE zzz_EmailQueue AS SELECT * FROM EmailQueue WHERE inqueue=1 LIMIT 3 FOR UPDATE;
.....
.....
#Section for other activities....
.....
.....
UPDATE EmailQueue SET inqueue=<<New_Value>> WHERE id IN (SELECT id FROM zzz_EmailQueue) AND inqueue=1;
COMMIT;
.......
#Remaining lines of Prodecure
.......
Update ** **Try with following method:
DECLARE v_EmailQueue_ID DOUBLE;
SELECT ID INTO v_EmailQueue_ID FROM EmailQueue WHERE inqueue = 0 LIMIT 1 FOR UPDATE;
UPDATE EmailQueue SET inqueue=1 WHERE id=v_EmailQueue_ID AND inqueue = 0;
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.