2008-09-23 113 views
4

我有一個函數,我使用名爲sqlf(),它模擬預準備語句。比如我可以做這樣的事情:「SELECT * FROM users where id IN()」== FAIL

 
$sql = sqlf("SELECT * FROM Users WHERE name= :1 AND email= :2",'Big "John"','[email protected]') ; 

由於種種原因,我不能使用準備好的語句,但我想效仿他們。我遇到的問題是與查詢如

 
$sql = sqlf("SELECT * FROM Users WHERE id IN (:1)",array(1,2,3)); 

我的代碼工作,但它失敗與空數組,例如,下面拋出一個mysql錯誤:

 
SELECT * FROM Users WHERE id IN(); 

有沒有人有任何建議?我應該如何將數組轉換並清空爲可以注入IN子句的sql?用NULL代替將不起作用。

回答

7

Null是您可以保證不在設置中的唯一值。它怎麼不是一種選擇?其他任何東西都可以看作潛在的一部分,它們都是價值。

+0

那麼我只是試過,它實際上工作。 「IN(NULL)」我認爲會和IS NULL做同樣的事情,但它們是不同的。感謝你的回答。 – jcampbell1 2008-09-24 00:02:29

0

是否有可能使用sqlf檢測空數組並將SQL更改爲不具有IN子句?

事實上,在將SQL傳遞給「真正的」SQL執行程序之前,您可以對SQL進行後處理,以便「IN()」部分被刪除,儘管您必須做各種欺騙以查看其他元素必須是什麼除去,使:

SELECT * FROM Users WHERE id IN(); 
SELECT * FROM Users WHERE a = 7 AND id IN(); 
SELECT * FROM Users WHERE id IN() OR a = 9; 

將成爲:

SELECT * FROM Users; 
SELECT * FROM Users WHERE a = 7; 
SELECT * FROM Users WHERE a = 9; 

這可能變得棘手取決於您的SQL的複雜性 - 你基本上需要一個完整的SQL語言解釋器。

-1

我認爲可以這樣做的唯一方法就是讓sqlf()函數掃描一下「IN(」後面是否有一個特定的替換出現,然後如果傳入的變量是一個空數組,你知道肯定不會在這一欄:"m,znmzcb~~1",這是一個黑客,當然,但它會工作

如果你想進一步,你可以改變你的功能,以便有不同類型的替換?它看起來像你的函數掃描一個冒號後跟一個數字,爲​​什麼不添加另一個類型,如@後跟一個數字,這將智能地清空數組(這可以讓你不必掃描和猜測如果變量應該是一個數組)

0

如果您的類似準備的函數只是用等價參數替換:1,您可以嘗試讓查詢包含類似(':1')的內容,以便如果:1爲空,則會解析爲('') ,這不會導致解析錯誤(但是如果該字段可以有空值,它可能會導致不良行爲 - 儘管如果它是一個int,這不是問題)。然而,這不是一個非常乾淨的解決方案,而且您最好檢測數組是否爲空,並簡單地使用缺少「IN(:1)」組件的替代版本的查詢。 (如果這是WHERE子句中唯一的邏輯,那麼可能你不想選擇所有東西,所以你根本就不會執行查詢。)

1

我想說,將一個空數組作爲參數傳入一個IN )子句是一個錯誤。調用此函數時,您可以控制查詢語法,因此您還應該對輸入負責。我建議在調用函數之前檢查參數的空白。

0

我會使用零,假設你的「id」列是一個pseudokey自動分配數字。

據我所知,大多數品牌的數據庫中的自動密鑰生成器都是從1開始的。這是一個約定,而不是要求(自動編號的字段沒有在標準SQL中定義)。但是這個約定很普遍,你可以依靠它。因爲零可能永遠不會出現在你的「id」列中,所以當你的輸入數組爲空時,你可以在IN()謂詞中使用這個值,並且它永遠不會匹配。

相關問題