2010-09-07 71 views
1

我正在構建一個基於$_GET參數傳入的動態更改的SQL查詢。我只是想知道,如果放入'虛擬'約束是'可接受'的做法,所以在添加新約束(每次)之前,我不必檢查SQL字符串是否存在'where'。SQL查詢構建實踐

例如, '假' 約束':

$sql = "select * from users u where u.id != 0";

現在,在每個塊,我確定我是否需要添加更多的約束,我可以這樣做:

if (!empty($uid)) 
    $sql .= " and (u.id = {$uid})"; 

而不是:

if (!empty($uid)) { 
    $sql .= strpos($sql, "where") === false ? " where " : " and "; 
    $sql .= " (u.id = {$uid})"; 
} 
+1

你爲什麼不寫一個名爲'addClause'的方法呢? – 2010-09-07 14:07:13

+0

是的......我理解你的評論 - 這就是我最終會做的,因爲沒有大量的重複代碼。但是,每次調用方法時,仍然會有同樣多的「存在」檢查。 – danjarvis 2010-09-07 14:10:34

+0

此代碼似乎很容易受到SQL注入攻擊。至於這個問題,你應該把它全部抽象出來放在一個'QueryBuilder'對象中。 – 2010-09-07 14:30:36

回答

2

我已經使用該約定(雖然我通常我們)根據您的RDBMS,使用列可能會影響性能。例如,如果您有一個索引,否則該索引是除該列外的覆蓋索引。

請確保您理解這種動態SQL的潛在缺陷,但如果這是您最終做的事情,那麼添加額外的一點似乎對我有意義。

0

從手動

SELECT * FROM table WHERE 1 

所以,是的,你可以做到這一點

1

而是附加到SQL字符串每次檢查的,你可以收集的條件:

if ($_GET["uid"]) { 
     $where[] = array("u.id =", $_GET->sql["uid"]); 

if ($_GET["photo"]) { 
     $where[] = array("u.has_photo =", 1); 

而且當您通過時完成SQL字符串:

foreach ($where as $add) { 
    $sql .= ...; 
} 

否則,這是一個可接受的方法。我不會使用大型武器,併爲此使用完整的ORM查詢生成器。