0

我正在尝试构建动态 PDO SQL 语句。关于如何做得更好的任何想法?

array(3) { [0]=> string(5) "00000" [1]=> NULL [2]=> NULL } free当我运行这个时,我不断得到......

所以我的 MySQL PDO 语句似乎不能正常工作!

关于如何解决这个问题的任何想法?

$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 * 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=".$i."
         OR a.status IS NOT NULL
         AND a.status IN ('Pending','Declined','Failed'))";

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

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

}
4

1 回答 1

0

一个有点可笑的事实。大家只SQL注入和prepared statements,而没有人想写代码:)

虽然我可以理解:PDO 在条件查询方面非常弱,所以这项任务会很辛苦。
与任何其他 API 一样,PDO 仅适用于初学者手册中的基本任务,并且对于任何现实生活中的问题都没有为开发人员提供真正的帮助。

所以,我给你一个safeMysql例子,它既安全方便
它与 PDO兼容,但您可以改用它并获得所有好处。

所以,这个想法不是在整个查询中解析占位符,而是在任意查询部分中解析。说,对于您的设施部分:

$fac_sql = '';
foreach($array as $facility){   
    if ($facility) {
       $fac_sql .= $db->parse(' AND facilities_id=?i',$facility);
    }
}

$fac_sql现在您在变量中有语法正确的语句。
其他部分也一样

$cond = '';
if($park!="Any") {
    $cond .= $db->parse(' AND b.park_id=?s',$park);
}
if($lecturestyle_id!="Any") {
    $cond .= $db->parse(" AND lecturestyle_id=?s",$lecturestyle_id);
}
if($roomstructure_id!="Any") {
    $cond .= $db->parse(" AND roomstructure_id=?s",$roomstructure_id);
}

...以及整个查询:

$sql = "
SELECT * 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 >= ?s;
?p
?p
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=?i
 OR a.status IS NOT NULL
 AND a.status IN ('Pending','Declined','Failed'))";

$rows = $db->getCol($sql,$group_size,$fac_sql,$cond,$i);

(代码未经测试,仅作为示例!)。

另一个 safeMysql 的好处是它会在出现错误时返回 Mysql 错误消息和整个查询。您将能够修复错误或在控制台中尝试查询以进行测试。

所以 - 这就是条件查询的一般情况。

至于您的特定查询问题 - 它与 PDO 或准备好的语句或条件查询构建无关。查询逻辑的某处存在缺陷。
您必须以纯文本形式编写查询并使用 console/phpadmin/sqlyog/whatever 进行尝试。您也可以在 stackoverflow 上寻求此SQL的帮助。
一旦您的查询开始工作,您就可以开始动态构建它。

另外,我觉得它太复杂了,需要简化。可以分成几个更简单的查询。同样循环运行这样的怪物也是一个很大的缺陷。最好在一次调用中重写它。

于 2013-02-20T07:04:20.510 回答