Сегодня это действительно является производным от моего предыдущего вопроса .
Я создал хранимую процедуру в моей базе данных, которую я хотел бы вызывать несколько раз подряд из PHP.
Скажем, это моя процедура:
CREATE PROCEDURE PROC_1( IN param1 VARCHAR(255), IN param2 VARCHAR(255)) BEGIN DECLARE ok INT; DECLARE success, failure VARCHAR(255); /* several SELECT, IF ... THEN, INSERT and UPDATE operations which then SET ok var to 0 or 1 */ IF ok = 1 THEN SET success = 'Everything went well'; SELECT success; LEAVE; ELSE SET failure = 'Problem description'; SELECT failure; LEAVE; END IF; END
Я сделал это так (короткая версия):
$calls = array( "CALL PROC_1('param1', 'param2')", "CALL PROC_1('param3', 'param4')", "CALL PROC_1('param5', 'param6')", ); // assuming I'm already connected to DB with $link foreach ($calls as $i => $call) { echo $i . ': '; $result = mysql_query($call); $ok = ($result === FALSE) ? FALSE : TRUE; var_dump($ok); if ($result !== FALSE) mysql_free_result($result); }
Первая итерация работает так, как ожидалось, но что-то после возврата FALSE
.
Почему это?
Пробовал mysqli
всякий случай, но получал точно такой же результат:
0: bool(true) 1: bool(false) 2: bool(false)
Что интересно, я проверил журналы MySQL (набор журналов для регистрации всех запросов), и только первый запрос когда-либо попадает на сервер. Следующие запросы никогда не попадают на сервер.
PS. Я запускаю PHP 5.3.2 и Apache 2.2.17.
ОБНОВИТЬ
Согласно предложению Шакти Сингха, я проверил состояние $link
перед запросом базы данных. Я заметил, что есть ошибка со второй итерации, поэтому вот результат с ошибкой:
ERROR: (0) 0: bool(true) ERROR: (0) ERROR: (0) 1: bool(false) ERROR: (2014) Commands out of sync; you can't run this command now ERROR: (2014) Commands out of sync; you can't run this command now 2: bool(false) ERROR: (2014) Commands out of sync; you can't run this command now
Кроме того, это появляется в журнале ошибок MySQL:
101126 15:46:28 [Warning] Aborted connection 129 to db: 'db1' user: 'root' host: 'localhost' (Got an error reading communication packets)
В php, когда мы вызываем хранимую процедуру в цикле, он просто выполняет ее один раз. Это происходит, когда хранимая процедура возвращает любой набор результатов. Я столкнулся с той же проблемой. У меня была хранимая процедура для обновления записей в таблице.
DELIMITER $$ DROP PROCEDURE IF EXISTS `espritkm`.`update_notification`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `update_notification`(item_id_val VARCHAR(11),item_source_val VARCHAR(50),item_type_id_val INT(50),item_type_val VARCHAR(50),created_at_val BIGINT(11),pivot_user_id_val VARCHAR(256),pivot_item_type_val VARCHAR(64),pivot_owner_type_val VARCHAR(64),pivot_owner_id_val INT(11),user_id_val VARCHAR(64), OUT row_effect VARCHAR(11)) Begin Declare item_count INT(10); SET @SQL1 = CONCAT('select count(*) into @item_count from item_notifications where item_id = ''', item_id_val, ''''); PREPARE S1 FROM @SQL1; EXECUTE S1; DEALLOCATE PREPARE S1; IF @item_count = 0 THEN SET @SQL2 = CONCAT('INSERT INTO item_notifications (item_id,item_source,item_type_id,item_type,created_at,pivot_user_id,pivot_item_type,pivot_owner_type,pivot_owner_id,user_id) value(''',item_id_val,''',''',item_source_val,''',''',item_type_id_val,''',''',item_type_val,''',''',created_at_val,''',''',pivot_user_id_val,''',''',pivot_item_type_val,''',''',pivot_owner_type_val,''',''',pivot_owner_id_val,''',''',user_id_val,''')'); PREPARE S2 FROM @SQL2; EXECUTE S2; DEALLOCATE PREPARE S2; SET row_effect= "Insert"; ELSE SET row_effect= "Update"; SET @SQL3 = CONCAT('UPDATE item_notifications SET viewer_id = ''',user_id_val,''' WHERE item_id = ''' ,item_id_val,'''') ; PREPARE S3 FROM @SQL3; EXECUTE S3; DEALLOCATE PREPARE S3; END IF; SELECT row_effect; END$$ DELIMITER ;
И это должно было быть выполнено для 1000 + строк, но выполнено только для одной записи.
Он не поддерживает в случае, когда ваш SP возвращает какой-либо набор данных. Просто исключите OUT var или любой оператор select (только для любой ссылки на результат), и он будет работать нормально.
Хранимая процедура может возвращать более одного набора результатов и всегда будет возвращать один дополнительный набор результатов, который не содержит никаких данных, кроме общей информации об ошибке / предупреждении о вызове процедуры в дополнение к любым явно возвращенным наборам результатов.
источник – http://forums.mysql.com/read.php?52,228296,228347#msg-228347