我有下面的代码,它可以正常工作并更新数组中包含的每个记录:
$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_multi_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);
但是现在它只对数组中的第一条记录执行一个UPDATE和一个INSERT,而忽略其他的
最佳答案
由于可重用性和安全性,@ RiggsFolly会针对已准备好的参数化语句和事务提供最佳建议,但是如果您希望/需要使用mysqli_multi_query
,(因为您不想在中间过渡到新的查询过程,项目或因为它对您而言没有吸引力),这是mysqli_multi_query
为您服务的方式:
查询组合:
如果SET值保持相同,而只有id
不同,则可以将所有UPDATE查询合并为一个查询。如果值是静态的,则可以使用implode();否则,可以选择在单个查询的SET子句中使用(详细/丑陋的)CASE语句,还是像在原始帖子中创建多个UPDATE查询之间进行选择。
$queries="UPDATE `stock` SET `signature_id`=0,`user_id`=0,`status_id`=1 WHERE `id` IN (".implode(',',$check_list).");";
与INSERT查询类似,它们都可以通过implode()或仅扩展VALUE部分的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());