2013-02-20 82 views
4

我正在將所有查詢切換到PDO格式,並且遇到涉及IN()子句的問題。帶有IN子句的MySQL PDO

$nba[0] = "Boston Celtics"; 
$nba[1] = "New York Knicks"; 
$nba[2] = "Houston Rockets"; 

$query = "SELECT game_id 
     FROM table 
     WHERE date_int >= :date_int 
     AND (home_team = :team OR away_team = :team) 
     AND home_team IN(:list) 
     AND away_team IN(:list) 
     ORDER BY game_date_int ASC 
     LIMIT 1";    
$stmt = $db->prepare($query); 
$stmt->execute(array(':date_int' => $limit, ':team' => $team, ':list' => implode(',', $nba))); 
+0

可能重複:我可以綁定一個數組到一個IN()條件?](http://stackoverflow.com/questions/920353/php-pdo-can-i-bind-an-array-to-an-in-condition) – MrCode 2013-02-20 08:44:58

回答

4

你可以解決這個問題是這樣的:

$nba = array(); 
$nba[0] = "Boston Celtics"; 
$nba[1] = "New York Knicks"; 
$nba[2] = "Houston Rockets"; 

$params = array(':date_int' => $limit, ':team' => $team); 
$nba_teams = array(); 
for($i=0;$i<count($nba);$i++){ 
    $nba_teams[] = ':list' . $i; 
    $params[':list' . $i] = $nba[$i]; 
} 

$query = "SELECT game_id 
    FROM table 
    WHERE date_int >= :date_int 
    AND (home_team = :team OR away_team = :team) 
    AND home_team IN(".implode(',', $nba_teams).") 
    AND away_team IN(".implode(',', $nba_teams).") 
    ORDER BY game_date_int ASC 
    LIMIT 1";    

$stmt = $db->prepare($query, $params); 
$stmt->execute(); 

沒有測試過,但我想你知道我想要的[PHP PDO

+0

這就是我要找的。一種將數組和非數組參數組合成單個關聯數組($ param)的方法,然後可以使用execute()語句而不是使用BindParam。感謝NLZ! :) – alds 2014-07-04 03:17:22

6

IN cannot be parameterized like other values。所以只需使用implode佔位符和值。儘管如此,我一直在考慮試圖在PHP中實現它。然而,我從來沒有想過要進一步思考。

我也看到你在查詢中有兩次相同的命名參數(:list)。如果您使用真實準備的語句,這也是不可能的。 Note that when you are using the mysql driver and PDO you have to disable emulated prepared statements

+2

+1指出非法相同參數(:列表)的多次使用以及有關禁用模擬預處理語句的其他信息。感謝PeeHaa – alds 2014-07-04 03:22:19

0

對於這樣的情況,PDO非常弱,所以這個任務將非常辛苦。
與其他任何API一樣,PDO僅適用於初學者手冊的基本任務,並且不會爲開發人員提供任何實際問題的實際幫助。
因此,開發人員必須採用某種抽象庫來讓它完成所有骯髒的工作。

所以,我給你一個safeMysql例如比PDO以任何方式更好:

$nba[0] = "Boston Celtics"; 
$nba[1] = "New York Knicks"; 
$nba[2] = "Houston Rockets"; 

$query = "SELECT game_id 
     FROM table 
     WHERE date_int >= ?i 
     AND (home_team = ?s OR away_team = ?s) 
     AND home_team IN(?a) 
     AND away_team IN(?a) 
     ORDER BY game_date_int ASC 
     LIMIT 1";    

$data = $db->getAll($query, $limit, $team, $team, $nba, $nba); 

看 - 這個代碼是整齊,簡潔明確。它只做有意義的事情,隱藏了綁定複雜數據的所有骯髒工作。 與醜陋代碼不同,您可以使用某些PHP和API函數玩這個代碼是可讀。這是重要的事情。你可以告訴這個代碼甚至在一年之後做了什麼。

NLZ的答案就是一個很好的例子 - 代碼被不必要的和令人費解的代碼所污染。
當您查找代碼時,您首先在尋找業務邏輯。代碼塊僅用於創建SQL查詢的一小部分,會讓您頭暈目眩,隱藏您的真實問題。
應該被移到內部後面的某處。

+1

'$ limit'做什麼?考慮到你在談論可讀性,有沒有什麼方法可以使用命名參數?否則:蛋糕是騙人的。 – PeeHaa 2013-02-20 09:03:43