代码之家  ›  专栏  ›  技术社区  ›  Drewy

带mysql会话变量的php准备语句

  •  0
  • Drewy  · 技术社区  · 6 年前

    我现在有下面的查询,它使用一个联合联接来连接两个查询,使用SQL变量来替代行在数字和活动计数之间的显示顺序。当我将集合行添加到查询中时,php文件有一个错误,当我删除它们时,查询将运行,但不检索任何值。我已经在服务器上运行了查询,它工作正常。

    如何在准备好的语句中使用SQL变量?如果不可能,我如何重写查询以获得相同的结果?

    SET @a = 0;
    SET @b = 0;
    SELECT * FROM(
        SELECT @a := @a + 1 AS sortOne, 1 AS sortTwo, tbl_company.comp_name AS comp_name, tbl_shift.shift_name AS shift_name,
                              SUM(tbl_short_term_programme.sun_p) AS sun_p_total, SUM(tbl_short_term_programme.sun_a) AS sun_a_total,
                              SUM(tbl_short_term_programme.mon_p) AS mon_p_total, SUM(tbl_short_term_programme.mon_a) AS mon_a_total,
                              SUM(tbl_short_term_programme.tue_p) AS tue_p_total, SUM(tbl_short_term_programme.tue_a) AS tue_a_total,
                              SUM(tbl_short_term_programme.wed_p) AS wed_p_total, SUM(tbl_short_term_programme.wed_a) AS wed_a_total,
                              SUM(tbl_short_term_programme.thu_p) AS thu_p_total, SUM(tbl_short_term_programme.thu_a) AS thu_a_total,
                              SUM(tbl_short_term_programme.fri_p) AS fri_p_total, SUM(tbl_short_term_programme.fri_a) AS fri_a_total,
                              SUM(tbl_short_term_programme.sat_p) AS sat_p_total, SUM(tbl_short_term_programme.sat_a) AS sat_a_total
                            FROM tbl_short_term_programme
                              INNER JOIN tbl_phase ON tbl_short_term_programme.phase_id = tbl_phase.phase_id
                              INNER JOIN tbl_company ON tbl_short_term_programme.company_id = tbl_company.company_id
                              INNER JOIN tbl_shift ON tbl_short_term_programme.shift_id = tbl_shift.shift_id
                            WHERE tbl_phase.phase_hash = ? AND YEARWEEK(tbl_short_term_programme.short_term_date, 2) = YEARWEEK(?, 2)
                            GROUP BY tbl_shift.shift_id, tbl_company.comp_name 
        UNION                             
        SELECT @b := @b + 1 AS sortOne, 2 AS sortTwo, tbl_company.comp_name AS comp_name, tbl_shift.shift_name AS shift_name,
                              COUNT(tbl_short_term_programme.sun_p) AS sun_p_total, COUNT(tbl_short_term_programme.sun_a) AS sun_a_total,
                              COUNT(tbl_short_term_programme.mon_p) AS mon_p_total, COUNT(tbl_short_term_programme.mon_a) AS mon_a_total,
                              COUNT(tbl_short_term_programme.tue_p) AS tue_p_total, COUNT(tbl_short_term_programme.tue_a) AS tue_a_total,
                              COUNT(tbl_short_term_programme.wed_p) AS wed_p_total, COUNT(tbl_short_term_programme.wed_a) AS wed_a_total,
                              COUNT(tbl_short_term_programme.thu_p) AS thu_p_total, COUNT(tbl_short_term_programme.thu_a) AS thu_a_total,
                              COUNT(tbl_short_term_programme.fri_p) AS fri_p_total, COUNT(tbl_short_term_programme.fri_a) AS fri_a_total,
                              COUNT(tbl_short_term_programme.sat_p) AS sat_p_total, COUNT(tbl_short_term_programme.sat_a) AS sat_a_total
                            FROM tbl_short_term_programme
                              INNER JOIN tbl_phase ON tbl_short_term_programme.phase_id = tbl_phase.phase_id
                              INNER JOIN tbl_company ON tbl_short_term_programme.company_id = tbl_company.company_id
                              INNER JOIN tbl_shift ON tbl_short_term_programme.shift_id = tbl_shift.shift_id
                            WHERE tbl_phase.phase_hash = ? AND YEARWEEK(tbl_short_term_programme.short_term_date, 2) = YEARWEEK(?, 2)
                            GROUP BY tbl_shift.shift_id, tbl_company.comp_name
    ) AS result ORDER BY sortOne, sortTwo
        $stmt->bind_param("ssss", $phase_hash, $formatted_date, $phase_hash, $formatted_date);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($comp_name, $shift_name, $sun_p_total, $sun_a_total, $mon_p_total, $mon_a_total, $tue_p_total,
                        $tue_a_total, $wed_p_total, $wed_a_total, $thu_p_total, $thu_a_total, $fri_p_total, $fri_a_total,
                        $sat_p_total, $sat_a_total);
        $row_array = array();
    
        while($stmt->fetch()) {
            $tmp = array();
            $tmp["shift_name"] = $shift_name;
            $tmp["comp_name"] = $comp_name;
            $tmp["sun_p_total"] = $sun_p_total;
            $tmp["sun_a_total"] = $sun_a_total;
            $tmp["mon_p_total"] = $mon_p_total;
            $tmp["mon_a_total"] = $mon_a_total;
            $tmp["tue_p_total"] = $tue_p_total;
            $tmp["tue_a_total"] = $tue_a_total;
            $tmp["wed_p_total"] = $wed_p_total;
            $tmp["wed_a_total"] = $wed_a_total;
            $tmp["thu_p_total"] = $thu_p_total;
            $tmp["thu_a_total"] = $thu_a_total;
            $tmp["fri_p_total"] = $fri_p_total;
            $tmp["fri_a_total"] = $fri_a_total;
            $tmp["sat_p_total"] = $sat_p_total;
            $tmp["sat_a_total"] = $sat_a_total;
            array_push($row_array, $tmp);
        }
        $stmt->close();
    
        echo json_encode($row_array);
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Barmar    6 年前

    正如比尔·卡尔文所说,在准备好的语句中只能运行一个查询。另一种解决方法是在与主查询联接的子查询中分配变量。

    SELECT * FROM(
        SELECT @a := @a + 1 AS sortOne, 1 AS sortTwo, tbl_company.comp_name AS comp_name, tbl_shift.shift_name AS shift_name,
              SUM(tbl_short_term_programme.sun_p) AS sun_p_total, SUM(tbl_short_term_programme.sun_a) AS sun_a_total,
              SUM(tbl_short_term_programme.mon_p) AS mon_p_total, SUM(tbl_short_term_programme.mon_a) AS mon_a_total,
              SUM(tbl_short_term_programme.tue_p) AS tue_p_total, SUM(tbl_short_term_programme.tue_a) AS tue_a_total,
              SUM(tbl_short_term_programme.wed_p) AS wed_p_total, SUM(tbl_short_term_programme.wed_a) AS wed_a_total,
              SUM(tbl_short_term_programme.thu_p) AS thu_p_total, SUM(tbl_short_term_programme.thu_a) AS thu_a_total,
              SUM(tbl_short_term_programme.fri_p) AS fri_p_total, SUM(tbl_short_term_programme.fri_a) AS fri_a_total,
              SUM(tbl_short_term_programme.sat_p) AS sat_p_total, SUM(tbl_short_term_programme.sat_a) AS sat_a_total
            FROM tbl_short_term_programme
              INNER JOIN tbl_phase ON tbl_short_term_programme.phase_id = tbl_phase.phase_id
              INNER JOIN tbl_company ON tbl_short_term_programme.company_id = tbl_company.company_id
              INNER JOIN tbl_shift ON tbl_short_term_programme.shift_id = tbl_shift.shift_id
              CROSS JOIN (SELECT @a := 0) AS var
            WHERE tbl_phase.phase_hash = ? AND YEARWEEK(tbl_short_term_programme.short_term_date, 2) = YEARWEEK(?, 2)
            GROUP BY tbl_shift.shift_id, tbl_company.comp_name 
        UNION                             
        SELECT @b := @b + 1 AS sortOne, 2 AS sortTwo, tbl_company.comp_name AS comp_name, tbl_shift.shift_name AS shift_name,
              COUNT(tbl_short_term_programme.sun_p) AS sun_p_total, COUNT(tbl_short_term_programme.sun_a) AS sun_a_total,
              COUNT(tbl_short_term_programme.mon_p) AS mon_p_total, COUNT(tbl_short_term_programme.mon_a) AS mon_a_total,
              COUNT(tbl_short_term_programme.tue_p) AS tue_p_total, COUNT(tbl_short_term_programme.tue_a) AS tue_a_total,
              COUNT(tbl_short_term_programme.wed_p) AS wed_p_total, COUNT(tbl_short_term_programme.wed_a) AS wed_a_total,
              COUNT(tbl_short_term_programme.thu_p) AS thu_p_total, COUNT(tbl_short_term_programme.thu_a) AS thu_a_total,
              COUNT(tbl_short_term_programme.fri_p) AS fri_p_total, COUNT(tbl_short_term_programme.fri_a) AS fri_a_total,
              COUNT(tbl_short_term_programme.sat_p) AS sat_p_total, COUNT(tbl_short_term_programme.sat_a) AS sat_a_total
            FROM tbl_short_term_programme
              INNER JOIN tbl_phase ON tbl_short_term_programme.phase_id = tbl_phase.phase_id
              INNER JOIN tbl_company ON tbl_short_term_programme.company_id = tbl_company.company_id
              INNER JOIN tbl_shift ON tbl_short_term_programme.shift_id = tbl_shift.shift_id
              CROSS JOIN (SELECT @b :- 0) AS var
            WHERE tbl_phase.phase_hash = ? AND YEARWEEK(tbl_short_term_programme.short_term_date, 2) = YEARWEEK(?, 2)
            GROUP BY tbl_shift.shift_id, tbl_company.comp_name
    ) AS result ORDER BY sortOne, sortTwo
    
        2
  •  0
  •   Bill Karwin    6 年前

    默认情况下,每次调用只能运行一个SQL语句 mysqli_prepare() .

    我建议在单独的语句中设置会话变量:

    $mysqli->query("set @a = 0, @b = 0");
    

    然后准备和执行大型查询。

    有些人可能会告诉你使用 mysqli_multi_query() 函数,但不能,因为它不支持准备好的语句。

    不过没关系,在一次通话中进行多个查询没有好处。只需在一个调用中设置变量,然后执行准备好的语句。只要您使用相同的DB连接,会话变量仍将具有它们的值。

    推荐文章