2010-07-16 72 views
3

你好我一直有在使用中的一些麻煩,其中使用MySQLi的條款,這是我的查詢:庫MySQLi在使用在有

 
SELECT * FROM core_tags WHERE tag_id IN (1,2,3,4,5) GROUP BY tag_id ORDER BY tag_popularity ASC 

如果我運行這個在PHP我聯繫,然後我按照我的預期得到5個結果。但是,如果我使用下面的代碼在PHP中運行它,我只會得到tag_id'1'的一個結果。

這是我的PHP。最初我是在課堂上使用函數來運行它,但是我手工編寫了代碼來測試它在我的函數中不僅僅是一個錯誤,而是出現了同樣的問題。

 
$mysqli = new mysqli(DB_SERVER, DB_NAME, DB_PASSWORD, DB_NAME); 
$rawQuery = 'SELECT * FROM core_tags WHERE tag_id IN (?) GROUP BY tag_id ORDER BY tag_popularity ASC'; 
$stmt = $mysqli->prepare($rawQuery); 
$stmt->bind_param("s", $tag_ids); 
$tag_ids = "1,2,3,4,5"; 
$stmt->execute(); 
$stmt->bind_result($tag_id, $tag_name, $tag_desc, $tag_popularity); 

while ($stmt->fetch()) { 
    printf ("%s\n", $tag_name); 
} 

$stmt->close(); 
die(); 

任何人都知道爲什麼mysqli版本只返回一行?使用mysql而不是mysqli也可以,與PHP My Admin相同。

回答

3

使用字符串預處理語句會導致你的最終SQL如下所示:

IN ('1,2,3,4,5') 

用引號,這不是你想要的。我會做到這一點:

$ids= array(1,2,3,4,5); 
$mysqli = new mysqli(DB_SERVER, DB_NAME, DB_PASSWORD, DB_NAME); 

$rawQuery = 'SELECT * FROM core_tags WHERE tag_id IN ('; 
$rawQuery .= implode(',',array_fill(0,count($ids),'?')); 
$rawQuery .= ') GROUP BY tag_id ORDER BY tag_popularity ASC'; 
$stmt = $mysqli->prepare($rawQuery); 
call_user_func_array(array($stmt,'bind_param'),$ids); 
$stmt->execute(); 
$stmt->bind_result($tag_id, $tag_name, $tag_desc, $tag_popularity); 

while ($stmt->fetch()) { 
    printf ("%s\n", $tag_name); 
} 

如果implode array_fill是混亂的,它只是創建相同大小的數組作爲$ids"?"滿,然後將它們轉向到CSV的簡寫方式。

UPDATE:非綁定PARAMS方式

當然,如果你想跳過綁定PARAMS廢話,你可以信任的$ids列表已經被消毒,你可以做到這一點,而是和跳過bind_params部分:

$rawQuery = 'SELECT * FROM core_tags WHERE tag_id IN ('; 
$rawQuery .= implode(',',$ids); 
$rawQuery .= ') GROUP BY tag_id ORDER BY tag_popularity ASC'; 

如果你不能信任的數據:

function clean_ids(&$item){ 
$item = intval($item); 
} 

$clean_ids = array_walk($ids,'clean_ids'); 
$rawQuery = 'SELECT * FROM core_tags WHERE tag_id IN ('; 
$rawQuery .= implode(',',$clean_ids); 
$rawQuery .= ') GROUP BY tag_id ORDER BY tag_popularity ASC'; 
+0

乾杯,這是我的想法可能需要被做,但感謝確定它應該工作。一個想法,是否有使用implode和array_full而不是像substr(str_repeat(「?,」,count($ ids)),0,-1)的原因;我不知道哪些更好的表現明智等 – Rob 2010-07-16 23:40:17

+0

@Rob,個人喜好。我喜歡使用數組。我會考慮關於性能問題的一個微觀優化問題。與數據庫調用相比,PHP執行任何一個操作的時間都是微乎其微的.-)。另外,請參閱更新的答案,我提供了兩種解決方法。 – 2010-07-16 23:43:17

+0

對於額外的例子來說,這是我的另一種選擇,但是我已經轉移到準備好的陳述中,我不想再次離開它。一件事。你的第一個例子給出了這個錯誤: 警告:mysqli_stmt :: bind_param()[mysqli-stmt.bind-param]:變量數量與預準備語句中的參數數量不匹配 我假設因爲它使用相同的變量每一次,因此不能被引用或類似的東西? – Rob 2010-07-16 23:49:21

2

我不確定PHP,但通常當你創建一個參數化查詢,就像你創建的參數化查詢一樣,只需使用一個參數來查看'IN'中的選項列表,你就可以得到如下的結果:

SELECT * FROM core_tags WHERE TAG_ID IN(「1,2,3」)

你想要什麼,不會做......你需要一個參數添加到查詢中在每個值你想要

+0

這似乎工作,但麥當查詢之間的id數量不同時,使用它非常困難。我會看看是否有其他人可以提供更好的解決方案,但謝謝你的貢獻。 – Rob 2010-07-16 23:04:10

+0

+1:Jaime,你對標準的SQL和參數化查詢是如何正確的。 @Rob:你想要的是動態SQL領域;在運行mysqli中的查詢字符串之前,您需要連接IN子句中的字符串值列表。 – 2010-07-16 23:08:22

+0

我通常最終迭代通過值的列表,並用這種方式手動構建IN部分...不知道如何在PHP中做到這一點,雖然 – Jaime 2010-07-16 23:11:47