php - 试图理解 php mysqli multi_query

标签 php mysql mysqli mysqli-multi-query

我有一个函数,旨在借助 sql 查询复制具有所有属性的产品。 我的问题是在完成后将 new_product_id 返回给 php。
如果我在 phpmyadmin 中运行 sql 脚本,一切正常。
如果我使用 php 函数运行 sql 脚本,则一切正常。
我需要帮助的是如何将 mysql-set-variable: @new_product_id 从上次查询分配给我想要返回的 php 变量。
----- sql查询------

CREATE TEMPORARY TABLE tmptable SELECT * FROM product WHERE id='19' AND site_id='1';
UPDATE tmptable SET id = 0,parent_id='19',status_id='1',name_internal=concat('NEW ',name_internal);
INSERT INTO product SELECT * FROM tmptable;
SET @new_product_id = LAST_INSERT_ID();
DROP TABLE tmptable;

CREATE TEMPORARY TABLE tmptable SELECT * FROM product_abcd WHERE product_id='19' AND site_id='1';
UPDATE tmptable SET product_id = @new_product_id,id=0;
INSERT INTO product_abcd SELECT * FROM tmptable;
DROP TABLE tmptable;

CREATE TEMPORARY TABLE tmptable SELECT * FROM product_efgh WHERE product_id='19' AND site_id='1';
UPDATE tmptable SET product_id = @new_product_id,id=0;
INSERT INTO product_efgh SELECT * FROM tmptable;
DROP TABLE tmptable;

(Here is more correct SQL insert statements)

SELECT @new_product_id AS new_product_id;
----- sql查询------
----- php函数(不完整)------
此功能正在制作产品的新副本,下面的代码不完整但有效,所以请只关注多查询部分。
//return 0 for fail or new product_id (!=0) for success
public function copyProduct($data){
 $res=0;
 //if something, build sql-query as 
 $sql="sql from above";
 //if we have a query to run
 if(!empty($sql)){
  //this is multi query, use correct function
  if ($this->connect()->multi_query($sql) === TRUE) {
  //loop it 
   while ($this->connect()->more_results()){
    $result=$this->connect()->next_result();
   }//while more results
 }//if multiquery ok
return $res;
}//end function copy
----- php函数(不完整)------
上面的代码有效,我得到了一个很好的产品副本
结果 =0 失败和
结果 1 成功,(这有效)
我希望它如何工作
结果= 0 失败和
结果= new_product_id 成功
所以我可以将用户重定向到新创建的产品,从而一键保存用户。
查询结果,来自 phpmyadmin 和来自 php 的结果(到目前为止一切正常,此时没有错误的查询)
  • Mysql 返回空结果(无行)(创建临时表)
  • 1 行受影响(更新 tmpt 表)
  • 1 排插入件(插入产品中)
  • mysql 返回 emtpy 结果(设置 $new_product_id)
  • mysql 返回空结果(删除 tmp 表)
  • mysql 返回空结果(创建临时表)
  • mysql x 行受影响(更新 tmp 表)
  • mysql x 行受影响(插入表中)
  • mysql 返回空结果(删除表 tmptable)
  • mysql 返回空结果(创建临时表)
    .... N.....
    最后一个查询“显示第 0-0 行(共 1 个)(选择 @new_product_id)
    new_product_id=25

  • 我尝试了什么?
    我将选择变量作为我的最终查询,我认为只检查最后一个查询并在那里分配变量是明智的,但是由于 php mysqli fetch_assoc 在非对象上是不可能的,我失败了。
    所以接下来不是那么光明,我知道我有 16 个来自 mysql 的结果,我只需要其中一个的结果,但无论如何我把它放在多查询中
    ----- php函数(不完整)------
    此功能正在制作产品的新副本,无法分配 new_product_id
    //return 0 for fail or new product_id (!=0) for success
    public function copyProduct($data){
     $res=0;
     //if something, build sql-query as 
     $sql="sql from above";
     //if we have a query to run
     if(!empty($sql)){
      //this is multi query, use correct function
      if ($this->connect()->multi_query($sql) === TRUE) {
      //loop it 
       while ($this->connect()->more_results()){
        //insert,update,drop will return false even if sql is ok, this would be sufficient for us now
        if ($result = $this->connect()->store_result()) {
         $row = $result->fetch_assoc();
         if(isset($row["new_product_id"])){
          //new return value of newly copied product
          $res=$row["new_product_id"];
          $result->free();
         }
        }
        $result=$this->connect()->next_result();
       }//while more results
     }//if multiquery ok
    return $res;
    }//end function copy
    
    ----- php函数(不完整)------
    检查 stackoverflow 上的其他问题建议发送多个普通查询,当 multi_query 存在时,这似乎是一个糟糕的解决方案。
    检查 php 库的 multiquery 对我没有好处,我无法理解它是如何工作的,因为许多其他人指出文档似乎是另一个函数的副本。

    最佳答案

    请记住 multi_query()向 MySQL 服务器发送一组 SQL 查询,但只等待第一个的执行。如果要使用 multi_query() 执行 SQL并仅获取最后一个查询的结果而忽略前一个查询,然后您需要执行一个阻塞循环并将结果缓冲到 PHP 数组中。遍历所有等待 MySQL 处理每个查询的结果,一旦 MySQL 响应,就没有更多结果,您可以保留最后获取的结果。
    例如,考虑这个函数。它将一堆串联的 SQL 查询发送到 MySQL 服务器,然后等待 MySQL 逐个处理每个查询。每个结果都被提取到 PHP 数组中,最后一个可用数组从函数中返回。

    function executeMultiQueryAndGetOnlyLastResult(mysqli $mysqli):array {
        $mysqli->multi_query('
        SELECT "a";
        SELECT 2;
        SELECT "val";
        ');
    
        $values = [];
    
        do {
            $result = $mysqli->use_result();
            if ($result) {
                // process the results here
                $values = $result->fetch_all();
                
                $result->free();
            }
        } while ($mysqli->next_result()); // next_result will block and wait for next query to finish on MySQL server
        $mysqli->store_result(); // Needed to fetch the error as exception
    
        return $values;
    }
    
    显然,将每个查询单独发送到 MySQL 会容易得多。 multi_query()非常复杂,用途也非常有限。如果您有许多无法通过 PHP 单独执行的 SQL 查询,它会很有用,但大多数时候您应该使用准备好的语句并分别发送每个查询。

    关于php - 试图理解 php mysqli multi_query,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63325991/

    相关文章:

    php - mysql中的"LIKE"

    c# - 如何在带有 Entity Framework 的 ASp.net 应用程序中同时使用 MySQL 和 MSSQL

    php - mysqli_fetch_all 不从一个特定表中检索记录

    php - MySQL插入语句后获取主键

    php - json_decode 为字符串变量返回 NULL

    php - 使用 Token 重置 Laravel 4.2 密码

    PHP 无休止地加载相同的内容

    PHP 循环,单独的结果取决于 group_id

    php - 为什么这个 MySQL Select 查询返回错误,但完全可以正常完成 Select?

    php - Mysqli 绑定(bind) - 未知数量的参数