微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

这实际上是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日志(设置为记录所有查询的日志记录),并且只有第一个查询到达了服务器.下一个查询永远不会到达服务器.

PS.我正在运行PHP 5.3.2和Apache 2.2.17.

UPDATE

根据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语句(仅用于任何结果引用),它就可以正常工作.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐