9

是否有可能有两个这样的mysqli查询?

mysqli_query($dblink, "INSERT INTO images (project_id, user_id, image_name, date_created, link_to_file, link_to_thumbnail, given_name) VALUES ('$project_id', '$user_id', '$image_name', '$date_created', '$link_to_file', '$thumbnail', '$ImageName')");
mysqli_query($dblink, "INSERT INTO images_history (project_id, user_id, image_name, date_created, link_to_file, link_to_thumbnail, given_name, day, month, year) VALUES ('$project_id', '$user_id', '$image_name', '$date_created', '$link_to_file', '$thumbnail', '$ImageName', '$day', '$month', '$year')");

基本上我想更新我的数据库中的两个表。有一个更好的方法吗?

4

3 回答 3

27

可以使用mysqli_multi_query()

例子:

<?php

$mysqli = new mysqli($host, $user, $password, $database);

// create string of queries separated by ;
$query  = "INSERT INTO images (project_id, user_id, image_name, date_created, link_to_file, link_to_thumbnail, given_name) VALUES ('$project_id', '$user_id', '$image_name', '$date_created', '$link_to_file', '$thumbnail', '$ImageName');";
$query .= "INSERT INTO images_history (project_id, user_id, image_name, date_created, link_to_file, link_to_thumbnail, given_name, day, month, year) VALUES ('$project_id', '$user_id', '$image_name', '$date_created', '$link_to_file', '$thumbnail', '$ImageName', '$day', '$month', '$year');";

// execute query - $result is false if the first query failed
$result = mysqli_multi_query($mysqli, $query);

if ($result) {
    do {
        // grab the result of the next query
        if (($result = mysqli_store_result($mysqli)) === false && mysqli_error($mysqli) != '') {
            echo "Query failed: " . mysqli_error($mysqli);
        }
    } while (mysqli_more_results($mysqli) && mysqli_next_result($mysqli)); // while there are more results
} else {
    echo "First query failed..." . mysqli_error($mysqli);
}

关键是,如果您想在一次调用中执行多个查询,则必须使用它。mysqli_multi_query出于安全原因,mysqli_query不会执行多个查询以防止 SQL 注入。

还要记住mysqli_store_result. FALSE如果查询没有结果集(哪些INSERT查询没有),则返回,因此您还必须检查它mysqli_error是否返回表示INSERT成功的空字符串。

请参阅:
mysqli_multi_query
mysqli_more_results
mysqli_next_result
mysqli_store_result

于 2012-06-07T00:54:11.267 回答
17

Stack Overflow 上的一些答案是如此自相矛盾,以至于令人震惊

关键是如果您想在一次调用中执行多个查询,则必须使用 mysqli_multi_query。出于安全原因,mysqli_query 不会执行多个查询以防止 SQL 注入

它基本上说,“关键是你必须使用没有安全扣的枪支,因为普通武器不会让你一脚射中自己。所以这里是打破它的方法,现在你可以瘫痪自己一口气!”

尽管 OP 没有询问如何在一次调用中运行两个查询,尽管引用了明确的警告,即在一次调用中运行多个查询的能力本质上是危险的,但答案漫不经心地提供了规避此限制的方法。

最糟糕的是,所有这些危险而繁琐的混乱都是徒劳的。仅仅是因为没有单一的理由在一次调用中运行多个查询。一个一个地运行查询是一个数据库 API 的用途

基本上我想更新我的数据库中的两个表。有一个更好的方法吗?

是的当然。只需使用两个准备好的查询。

$stmt = $dblink->prepare("INSERT INTO images 
(project_id, user_id, image_name, date_created, link_to_file, link_to_thumbnail, given_name) 
VALUES (?,?,?,?,?,?,?)");
$stmt->bind_param("ssssss", $project_id, $user_id, $image_name, $date_created, $link_to_file, $thumbnail, $ImageName);
$stmt->execute();

$stmt = $dblink->prepare("INSERT INTO images_history 
(project_id, user_id, image_name, date_created, link_to_file, link_to_thumbnail, given_name, day, month, year)
VALUES (?,?,?,?,?,?,?,?,?,?)");
$stmt->bind_param("ssssssssss", $project_id, $user_id, $image_name, $date_created, $link_to_file, $thumbnail, $ImageName, $day, $month, $year);
$stmt->execute();

它不仅更干净,而且100% 安全,不受 SQL 注入的影响。

如果您的查询之一失败,只需向 mysqli 询问错误消息,然后修复错误

于 2019-11-09T20:09:39.137 回答
1

一劳永逸!使用此函数可以在脚本中的任何位置获取无限数量的查询结果。

功能:

您只需将多查询的输出传递给函数,它就会返回在每个查询中找到的所有结果和错误。

  function loop_multi($result){
    //use the global variable $conn in this function
    global $conn;
    //an array to store results and return at the end
    $returned = array("result"=>array(),"error"=>array());
    //if first query doesn't return errors
      if ($result){
        //store results of first query in the $returned array
        $returned["result"][0] = mysqli_store_result($conn);
        //set a variable to loop and assign following results to the $returned array properly
        $count = 0;
        // start doing and keep trying until the while condition below is not met
        do {
            //increase the loop count by one
            $count++;
            //go to the next result
            mysqli_next_result($conn);
            //get mysqli stored result for this query
            $result = mysqli_store_result($conn);
            //if this query in the loop doesn't return errors
            if($result){
              //store results of this query in the $returned array
              $returned["result"][$count] = $result;
            //if this query in the loop returns errors
            }else{
              //store errors of this query in the $returned array
              $returned["error"][$count] = mysqli_error($conn);
            }
        }
        // stop if this is false
        while (mysqli_more_results($conn));
      }else{
        //if first query returns errors
        $returned["error"][0] = mysqli_error($conn);
      }
    //return the $returned array
    return $returned;
  }

用法:

$query  = "INSERT INTO table1 (attribute1) VALUES ('value1');";
$query .= "INSERT INTO table2 (attribute2) VALUES ('value2');";
$query .= "SELECT * FROM table3;";

//execute query
$result = mysqli_multi_query($conn, $query);
//pass $result to the loop_multi function
$output = loop_multi($result);

输出

$output 包括按查询排序的 2 个数组“结果”和“错误”。例如,如果您需要检查执行第三个查询时是否发生任何错误并获取其结果,您可以这样做:

if(isset($output['error'][2]) && $output['error'][2] !== ""){
  echo $output['error'][2];
}else{
  while($row = $output['result'][2]->fetch_assoc()) {
    print_r($row);
  }
}
于 2017-09-11T06:46:34.660 回答