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

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

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

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

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

  1. $check_list = isset($_POST['check_list']) ? $_POST['check_list'] : array();
  2. foreach($check_list as $check_list) {
  3. $query = "UPDATE `stock` SET `signature_id` = 0,
  4. user_id = 0,
  5. `status_id` = 1
  6. WHERE `id` = '$check_list';
  7. INSERT INTO `returned`
  8. (`id`, `stock_id`, `signature_id`,
  9. `user_id`, `timestamp`)
  10. VALUES ('','$check_list','$id',
  11. '$user_id',now())";
  12. $result = mysqli_multi_query($conn, $query);

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

toiithl6

toiithl61#

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

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

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

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

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

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

  1. mysqli_multi_query($conn,$queries)

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

  1. if(mysqli_multi_query($conn,$queries)){
  2. do{
  3. echo "<br>Rows = ",mysqli_affected_rows($conn);
  4. } while(mysqli_more_results($conn) && mysqli_next_result($conn));
  5. }
  6. if($mysqli_error=mysqli_error($conn)){
  7. echo "<br>Syntax Error: $mysqli_error";
  8. }

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

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

数据库设置为:

  1. CREATE TABLE `stock` (
  2. id int(10) NOT NULL AUTO_INCREMENT,
  3. signature_id int(10) NOT NULL,
  4. user_id int(10) NOT NULL,
  5. status_id int(10) NOT NULL,
  6. PRIMARY KEY (id)
  7. );
  8. CREATE TABLE `returned` (
  9. id int(10) NOT NULL AUTO_INCREMENT,
  10. stock_id int(10) NOT NULL,
  11. signature_id int(10) NOT NULL,
  12. user_id int(10) NOT NULL,
  13. `timestamp` datetime NOT NULL,
  14. PRIMARY KEY (id)
  15. );
  16. /* Declaring your `id` columns with AUTO_INCREMENT means you can omit them from your INSERT query. */
  17. /* 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. */
  18. INSERT INTO `stock` (`signature_id`,`user_id`,`status_id`) VALUES
  19. (1,1,1),
  20. (2,2,2),
  21. (3,3,3),
  22. (4,4,4),
  23. (5,5,5),
  24. (6,6,6),
  25. (7,7,7),
  26. (8,8,8),
  27. (9,9,9),
  28. (10,10,10),
  29. (11,11,11),
  30. (12,12,12);

生成的查询如下所示:

  1. 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());
展开查看全部

相关问题