duandeng2265 2015-12-14 12:39
浏览 86
已采纳

mySQL句子的问题包括两个临时表创建

I have a mySQL sentence that works like a charm if I execute it in my phpMyAdmin:

CREATE TEMPORARY TABLE hash1
      SELECT * FROM
      (
        (
            SELECT DISTINCT feature_id AS fl, feature_value AS fv FROM gf_product_features WHERE feature_id = '1' AND feature_value = 'No frost total'
        ) UNION 
        (
            SELECT DISTINCT feature_id AS fl, feature_value AS fv FROM gf_product_features WHERE feature_id = '3' AND feature_value = '43'
        )) AS q;


      CREATE TEMPORARY TABLE hash2
        SELECT * FROM hash1;

        SELECT 
          p.id AS id, 
          p.main_image AS main_image, 
          p.type AS taxonomy, 
          p.name AS model, 
          p.sku AS sku, 
          p.price AS price, 
          b.brand_name AS brand_name, 
          b.brand_image AS brand_logo,
          pf.feature_value AS feature_value, 
          f.feature AS feature_label,
          f.id AS feature_id
        FROM
        (
          SELECT  a.*
          FROM    gf_product AS a
          INNER JOIN
          (
            SELECT product_id
            FROM
            (
              SELECT a.product_id , count(*) AS commons
              FROM   gf_product_features AS a
              INNER JOIN hash1 AS b 
                ON    a.feature_id = b.fl 
                AND   a.feature_value = b.fv 
              GROUP BY a.product_id 
              ) AS features
              WHERE commons = (SELECT count(*) AS count FROM hash2)  
            ) b1 ON a.id = b1.product_id 
          ) AS p
        INNER JOIN  gf_brands AS b 
            ON p.brand_id = b.id
        INNER JOIN  gf_product_features AS pf 
            ON pf.product_id = p.id   
        INNER JOIN  gf_features AS f 
            ON pf.feature_id = f.id
        ORDER BY    price ASC, 
                    feature_id ASC

I want to execute a php function through Ajax request, that constructs dinamically the sql sentence above, but I'm always getting this error in my browser's console:

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TEMPORARY TABLE hash2
        SELECT * FROM hash1;

        SELECT 
       ' at line 12

And thus, the following error too:

Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in /www/htdocs/example/inc/functions.php on line 538

Which corresponds to this line of my php code:

while ($row = mysqli_fetch_assoc($result))

Maybe clone hash2 table from hash1 table

CREATE TEMPORARY TABLE hash2
        SELECT * FROM hash1;

sounds weird, but if I don't do this in that way, in my phpMyAdmin I get this error:

 #1137 - Can't reopen table: 'b'

I can't realize why my sql sentence works fine in my phpMyadmin but, when I construct it on my php file it doesn't works. Can anybody help me, please?

For further information, this is my PHP code:

    function getProductsFromFilteredQuery($connection, $filters, &$html)
{
    $sql = '';
    $m = count($filters); // $filters are an array of values like this: ['value1A, value2A', 'value1B, value2B', ...]

    $sql = 'CREATE TEMPORARY TABLE hash1
      SELECT * FROM
      (';

    for ($n = 0; $n < $m; $n++)
    {
        $string                 = explode(', ', $filters[$n]);
        $feature_id         = $string[0];
        $feature_value  = $string[1];

        $sql .= "
        (
            SELECT DISTINCT feature_id AS fl, feature_value AS fv FROM gf_product_features WHERE feature_id = '" . $feature_id . "' AND feature_value = '" . $feature_value . "'
        )";

        if ($n < ($m - 1))
        {
            $sql .= ' UNION ';
        }
    }


    $sql .=  ') AS q;


      CREATE TEMPORARY TABLE hash2 -- In this line I get an error
        SELECT * FROM hash1;

        SELECT 
          p.id AS id, 
          p.main_image AS main_image, 
          p.type AS taxonomy, 
          p.name AS model, 
          p.sku AS sku, 
          p.price AS price, 
          b.brand_name AS brand_name, 
          b.brand_image AS brand_logo,
          pf.feature_value AS feature_value, 
          f.feature AS feature_label,
          f.id AS feature_id
        FROM
        (
          SELECT  a.*
          FROM    gf_product AS a
          INNER JOIN
          (
            SELECT product_id
            FROM
            (
              SELECT a.product_id , count(*) AS commons
              FROM   gf_product_features AS a
              INNER JOIN hash1 AS b 
                ON    a.feature_id = b.fl 
                AND   a.feature_value = b.fv 
              GROUP BY a.product_id 
              ) AS features
              WHERE commons = (SELECT count(*) AS count FROM hash2)  
            ) b1 ON a.id = b1.product_id 
          ) AS p
        INNER JOIN  gf_brands AS b 
            ON p.brand_id = b.id
        INNER JOIN  gf_product_features AS pf 
            ON pf.product_id = p.id   
        INNER JOIN  gf_features AS f 
            ON pf.feature_id = f.id
        ORDER BY    price ASC, 
                    feature_id ASC';

    $result = mysqli_query($connection, $sql);

    while ($row = mysqli_fetch_assoc($result)) // In this line I get an error too
    {
        // Do some stuff... and at last, return the resulting $html
    }
};
  • 写回答

1条回答 默认 最新

  • doumo1807831 2015-12-14 14:25
    关注

    I finally could find the error. In my phpMyAdmin it worked as well because someone can execute several queries in the SQL console. There is no problem with it.

    However, when coding an mySQL query through PHP you only can run one mySQL sentence at once. Well, there is an exception: You can use mysqli_multi_query + mysqli_more_results, or something like these. But as I was coded it, you can't.

    So there is two options: rewrite the PHP code like described in the pages of the two links above, or doing several mysqli_query within the PHP function.

    I decided to do it through the second option, so the working code is the following (Notice the comments after each mysqli_query):

    function getProductsFromFilteredQuery($mysqli, $filters, &$html) {
    $sql = '';
    $m = count($filters);
    
    $sql        = 'DROP TEMPORARY TABLE IF EXISTS hash1;';
    $result = mysqli_query($mysqli, $sql); // A single query
    
    $sql        = 'DROP TEMPORARY TABLE IF EXISTS hash2;';
    $result = mysqli_query($mysqli, $sql); // Another single query
    
    $sql        = 'CREATE TEMPORARY TABLE hash1
      SELECT * FROM
      (';
    
    for ($n = 0; $n < $m; $n++)
    {
        $string                 = explode(', ', $filters[$n]);
        $feature_id         = $string[0];
        $feature_value  = $string[1];
    
        $sql .= "
        (SELECT DISTINCT feature_id AS fl, feature_value AS fv FROM gf_product_features WHERE feature_id = '" . $feature_id . "' AND feature_value = '" . $feature_value . "')";
    
        if ($n < ($m - 1))
        {
            $sql .= ' UNION ';
        }
    }
    
    
    $sql .=  ') AS q1';
    $result = mysqli_query($mysqli, $sql); // Another single query
    
    $sql =  'CREATE TEMPORARY TABLE hash2
        SELECT * FROM hash1;';
    $result = mysqli_query($mysqli, $sql);  // Another single query
    
    $sql = 'SELECT 
                  p.id AS id, 
                  p.main_image AS main_image, 
                  p.type AS taxonomy, 
                  p.name AS model, 
                  p.sku AS sku, 
                  p.price AS price, 
                  b.brand_name AS brand_name, 
                  b.brand_image AS brand_logo,
                  pf.feature_value AS feature_value, 
                  f.feature AS feature_label,
                  f.id AS feature_id
                FROM
                (
                  SELECT  a.*
                  FROM    gf_product AS a
                  INNER JOIN
                  (
                    SELECT product_id
                    FROM
                    (
                      SELECT a.product_id , count(*) AS commons
                      FROM   gf_product_features AS a
                      INNER JOIN hash1 AS b 
                        ON    a.feature_id = b.fl 
                        AND   a.feature_value = b.fv 
                      GROUP BY a.product_id 
                      ) AS features
                      WHERE commons = (SELECT count(*) AS count FROM hash2)  
                    ) b1 ON a.id = b1.product_id 
                  ) AS p
                INNER JOIN  gf_brands AS b 
                    ON p.brand_id = b.id
                INNER JOIN  gf_product_features AS pf 
                    ON pf.product_id = p.id   
                INNER JOIN  gf_features AS f 
                    ON pf.feature_id = f.id
                ORDER BY    price ASC, 
                            feature_id ASC';
    
    $result = mysqli_query($mysqli, $sql);  // Another single query. The last one.
    
    while ($row = mysqli_fetch_assoc($result))
    {
        // My stuff here...
    }
    }; // @END of function
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?