gpt4 book ai didi

php - 在 foreach 循环中调用存储过程 - 仅首先执行

转载 作者:行者123 更新时间:2023-11-29 05:44:01 25 4
gpt4 key购买 nike

这真的是my earlier question today的导数.

我在我的数据库中创建了一个存储过程,我想从 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 日志(日志记录设置为记录所有查询),只有第一个查询到达服务器。下一个查询永远不会到达服务器。

附言。我正在运行 PHP 5.3.2 和 Apache 2.2.17。


更新

根据 Shakti Singh 的建议,我在查询数据库之前检查了 $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 语句(仅用于任何结果引用),它就可以正常工作。

关于php - 在 foreach 循环中调用存储过程 - 仅首先执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4285837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com