构建动态查询时,绑定变量的数量与令牌错误的数量不匹配

时间:2013-02-20 00:49:29

标签: php mysql pdo

我一直收到以下错误:

  

警告:PDOStatement :: execute():SQLSTATE [HY093]:参数无效   number:boundvariables的数量与令牌数量不匹配

尝试构建动态SQL查询时。知道损坏在哪里吗?我搜索了几个小时但仍然没有运气

$park = $_POST["park"];
$lecturestyle_id = $_POST["lecturestyle"];
$group_size = $_POST["groupsize"];
$roomstructure_id = $_POST["roomstructure"];
$array = explode(",", $_POST["facilities"]);

// change Mon here

echo '<td class="gridSide">
Mon
';

// build facilities search

for($i = 0; $i < count($array); $i++){  
    if ($array[$i]!=0) {
    $fac .= ' AND facilities_id='.$array[$i].'';
    }
    else
    $fac .= '';
}

echo '</td>';


for ($i = 1; $i <= 9; $i++) 
{

        // change mon here

        echo '<td class="box" id="mon'.$i.'">';

        // dynamically build sql query

        $sql = 
        "
        SELECT DISTINCT COUNT(*) FROM ts_room rm
        LEFT JOIN ts_roomfacilities rf
        ON rm.id = rf.room_id
        LEFT join ts_facilities f
        ON f.id = rf.facilities_id
        LEFT JOIN ts_building b
        ON rm.building_id=b.id
        WHERE capacity>=:group_size";

        $sql .= $fac;

        if($park!="Any") {
        $sql .= " AND b.park_id=:park";
        }

        if($lecturestyle_id!="Any") {
        $sql .= " AND lecturestyle_id=:lecturestyle_id";
        }

        if($roomstructure_id!="Any") {
        $sql .= " AND roomstructure_id=:roomstructure_id";
        }

        $sql .= " AND rm.id NOT IN
        (SELECT COUNT(*)
         FROM ts_request rq
         LEFT JOIN ts_allocation a ON a.request_id = rq.id
         WHERE 
         day_id=1 AND period_id=:period
         OR a.status IS NOT NULL
         AND a.status IN ('Pending','Declined','Failed'))";

         $stm = $pdo->prepare( $sql );
         $stm->execute( array( ':roomstructure_id' => $roomstructure_id, ':lecturestyle_id' => $lecturestyle_id, 
         ':group_size' => $group_size, ':park' => $park, ':period' => $i));
         $rows = $stm->fetchColumn();

         echo $rows.'<br>free</td>';            
         echo '</td>';

}

2 个答案:

答案 0 :(得分:1)

当您执行$stm->exectue时,您将为':roomstructure_id'':lecturestyle_id'':group_size'':park'':period'提供令牌,而不管其是什么是否实际上存在于查询中,即它们中的任何一个是否等于'Any'

您应该在构建查询时构建值数组...只要字段的搜索值 'Any',就可以为其添加值。

例如

if($park!="Any") {
    $sql .= " AND b.park_id=:park";
    $searchArray[':park'] = $park;
}

答案 1 :(得分:0)

您未分配:group_size参数,而$stm->execute()接受单维数组。

试试这个:

<?php
require_once("../resources/php/connection.php");

$park = $_POST["park"];
$lecturestyle_id = $_POST["lecturestyle"];
$group_size = $_POST["groupsize"];
$roomstructure_id = $_POST["roomstructure"];
$array = explode(",", $_POST["facilities"]);

// change Mon here
echo '<td class="gridSide">Mon';

// build facilities search
echo '</td>';

$fac = null;
for($i = 0; $i < count($array); $i++){
    if ($array[$i]!=0) {
        $fac .= ' AND facilities_id='.$array[$i].'';
    }
}

for ($i = 1; $i <= 9; $i++){

    // change mon here
    echo '<td class="box" id="mon'.$i.'">';

    // dynamically build sql query
    $sql ="SELECT DISTINCT COUNT(*) FROM ts_room rm
                    LEFT JOIN ts_roomfacilities rf
                    ON rm.id = rf.room_id
                    LEFT join ts_facilities f
                    ON f.id = rf.facilities_id
                    LEFT JOIN ts_building b
                    ON rm.building_id=b.id
                    WHERE capacity >= :group_size";

    $sql .= $fac;

    if($park!="Any") {
        $sql .= " AND b.park_id=:park";
        $searchArray[':park'] = $park;
    }

    if($lecturestyle_id!="Any") {
        $sql .= " AND lecturestyle_id=:lecturestyle_id";
        $searchArray[':lecturestyle_id'] = $lecturestyle_id;
    }

    if($roomstructure_id!="Any") {
        $sql .= " AND roomstructure_id=:roomstructure_id";
        $searchArray[':roomstructure_id'] = $roomstructure_id;
    }

    $sql .= " AND rm.id NOT IN
                    (SELECT COUNT(*)
                     FROM ts_request rq
                     LEFT JOIN ts_allocation a ON a.request_id = rq.id
                     WHERE
                     day_id=1 AND period_id=:period
                     OR a.status IS NOT NULL
                     AND a.status IN ('Pending','Declined','Failed'))";
    //Dont forget these
    $searchArray[':period'] = $i;
    $searchArray[':group_size'] = $group_size;

    $stm = $pdo->prepare($sql);
    $stm->execute($searchArray);
    $rows = $stm->fetchColumn();

    echo $rows.'<br>free</td>';
    echo '</td>';

}
?>