foreach与mysqli\u多\u查询问题

nr7wwzry  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(315)

我有以下代码,可以正常工作并更新数组中包含的每条记录:

$check_list = isset($_POST['check_list']) ? $_POST['check_list'] : array();  
foreach($check_list as $check_list) {
$query = "UPDATE `stock` SET `signature_id` = 0, 
                              user_id = 0, 
                             `status_id` = 1 
            WHERE `id` = '$check_list'";
$result = mysqli_query($conn, $query);

我现在需要它为数组中的每个结果执行多个查询,因此我使用mysqli\u multi\u query将代码更改为:

$check_list = isset($_POST['check_list']) ? $_POST['check_list'] : array();  
foreach($check_list as $check_list) {
    $query = "UPDATE `stock` SET `signature_id` = 0, 
                                  user_id = 0, 
                                 `status_id` = 1 
                WHERE `id` = '$check_list';
               INSERT INTO `returned`
                        (`id`, `stock_id`, `signature_id`, 
                        `user_id`, `timestamp`) 
                VALUES ('','$check_list','$id',
                        '$user_id',now())";
    $result = mysqli_multi_query($conn, $query);

但它现在只对数组中的第一条记录执行一次更新和一次插入,而忽略其他记录

toiithl6

toiithl61#

@riggsfully提供了关于准备好的参数化语句和事务的最佳建议,因为它具有可重用性和安全性,但是如果您想/需要继续使用它的话 mysqli_multi_query ,(因为您不想在项目中期过渡到新的查询流程,或者因为它对您没有吸引力)下面是 mysqli_multi_query 我们可以为您服务:
查询组合:
如果设定值保持不变 id 的不同,所有更新查询都可以合并到单个查询中。如果这些值是静态的,那么可以使用implode(),如果不是,那么可以选择在单个查询的set子句中使用(verbose/ught)case语句,或者在原始post中创建多个update查询。

$queries="UPDATE `stock` SET `signature_id`=0,`user_id`=0,`status_id`=1 WHERE `id` IN (".implode(',',$check_list).");";

同样,对于insert查询,它们都可以通过implode()或foreach循环合并到一个语句中,foreach循环只扩展值部分。

$queries.="INSERT INTO `returned` (`stock_id`,`signature_id`,`user_id`,`timestamp`) VALUES ('".implode("','$id','$user_id',now()),('",$check_list)."','$id','$user_id',now());";

$queries.="INSERT INTO `returned` (`stock_id`,`signature_id`,`user_id`,`timestamp`) VALUES ";
foreach($check_list as $k=>$check_list){
    // manipulate $id and $user_id as needed
    $queries.=($k==0?"":",")."('$check_list','$id','$user_id',now())";
}

故障意识:
如果您不需要任何类型的成功迹象,那么一行代码就可以了(当然,不要让它出现在任何循环之外):

mysqli_multi_query($conn,$queries)

否则,您将需要稍大一点的代码块:

if(mysqli_multi_query($conn,$queries)){
    do{
        echo "<br>Rows = ",mysqli_affected_rows($conn);
    } while(mysqli_more_results($conn) && mysqli_next_result($conn));
}
if($mysqli_error=mysqli_error($conn)){
    echo "<br>Syntax Error: $mysqli_error";
}

我已经对这两个查询使用implode()测试了我的解决方案,并成功地使用了:

$check_list=array(1,3,5,6,10,11);

数据库设置为:

CREATE TABLE `stock` (
    id int(10) NOT NULL AUTO_INCREMENT,
    signature_id int(10) NOT NULL,
    user_id int(10) NOT NULL,
    status_id int(10) NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE `returned` (
    id int(10) NOT NULL AUTO_INCREMENT,
    stock_id int(10) NOT NULL,
    signature_id int(10) NOT NULL,
    user_id int(10) NOT NULL,
    `timestamp` datetime NOT NULL,
    PRIMARY KEY (id)
);

/* Declaring your `id` columns with AUTO_INCREMENT means you can omit them from your INSERT query. */
/* Depending on your mysql version, creating a default datetime for `timestamp` may be possible which then would permit omitting `timestamp` from your INSERT query too. */

INSERT INTO `stock` (`signature_id`,`user_id`,`status_id`) VALUES
    (1,1,1),
    (2,2,2),
    (3,3,3),
    (4,4,4),
    (5,5,5),
    (6,6,6),
    (7,7,7),
    (8,8,8),
    (9,9,9),
    (10,10,10),
    (11,11,11),
    (12,12,12);

生成的查询如下所示:

UPDATE `stock` SET `signature_id`=0,`user_id`=0,`status_id`=1 WHERE `id` IN (1,3,5,6,10,11);INSERT INTO `returned` (`stock_id`,`signature_id`,`user_id`,`timestamp`) VALUES ('1','','',now()),('3','','',now()),('5','','',now()),('6','','',now()),('10','','',now()),('11','','',now());

相关问题