2014-06-15 3 views
0

Я работаю над приложением, для которого мне нужно прочитать m строк за время из итоговых строк «N», где m < N. Каждый раз, когда я читаю строки «m», я должен установить их статус read в той же таблице.SELECT и UPDATE те же строки в хранимой процедуре MYSQL

Для примера рассмотрим следующую таблицу

+------+-------------------------+--------------------------+----------+-------+---------+------+ 
| ID | from_email_address  | to_email_address   | subject | body | inqueue | sent | 
+------+-------------------------+--------------------------+----------+-------+---------+------+ 
| 1 | [email protected] | [email protected] | Subject1 | Body1 |   0 | 0 | 
| 2 | [email protected] | [email protected] | Subject1 | Body1 |   0 | 0 | 
| 3 | [email protected] | [email protected] | Subject1 | Body1 |  0  | 0 | 
| 4 | [email protected] | [email protected]  | Subject1 | Body1 |  0  | 0 | 
| 5 | [email protected] | [email protected]  | Subject1 | Body1 |   0 | 0 | 
| 6 | [email protected] | [email protected] | Subject1 | Body1 |  0 | 0 | 
| 7 | [email protected] | [email protected] | Subject1 | Body1 |  0 | 0 | 
+------+-------------------------+--------------------------+----------+-------+---------+------+ 

Я хочу читать позволяет говорить 3 rows в то время, и как только я прочитал строки, я хочу, чтобы установить inqueue статус этих строк, как 1.

я могу использовать следующий запрос в хранимой процедуре, чтобы выбрать строки

select * from EmailQueue where inqueue=1 LIMIT 3 

После этого, как обновить ту же строку и установить их inqueue в 1.

EDIT

Вот хранимая процедура я создал, выдающий ошибку.

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 

Это дает следующие ошибки при вызове

ERROR 1746 (HY000): Can't update table 'emailqueue' while 'temp_EmailQueue' is being created.

ответ

0

Предложив использовать Transaction и "SELECT FOR UPDATE", чтобы выполнить ваши требования.

Пожалуйста, обратитесь следующие ссылки на примеры:

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 - Добавлена ​​QUERY Пример:

Пример:

....... 
#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 ** ** Попробуйте с следующим способом:

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; 
+0

Это нормально. Но какой запрос использовать для обновления только тех строк, которые были выбраны с помощью запроса SELECT? – kaysush

+0

@kaysush - проверьте обновления. –

+0

Я попробовал ваше решение, но когда я вызываю процедуру, он говорит: «ERROR 1746 (HY000): не удается обновить таблицу« emailqueue », пока создается« zzz_EmailQueue ».« Пожалуйста, проверьте обновление. – kaysush

Смежные вопросы