2011-05-12 107 views
3

根據程序中的某些變量,具有可以爲NULL的參數的select查詢的最佳方式是什麼?sql select可以爲NULL的參數

我能想到的兩種解決方案(僞)的:

bool valueIsNull; 
int value; 

query = "SELECT * FROM table WHERE field "; 

if (valueIsNull) 
{ 
    query += "IS NULL"; 
} 
else 
{ 
    query += "= ?"; 
} 
statement st = sql.prepare(query); 

if (!valueIsNull) 
{ 
    st.bind(0, value); 
} 

bool valueIsNull; 
int value; 

query = "SELECT * FROM table WHERE field = ? OR (? IS NULL AND field IS NULL)"; 
statement st = sql.prepare(query); 
if (valueIsNull) 
{ 
    st.bindNull(0); 
    st.bindNull(1); 
} 
else 
{ 
    st.bind(0, value); 
    st.bind(1, value); 
} 

這只是一個簡單的SELECT語句大量的代碼,我覺得它只是醜陋和不明確的。

最乾淨的方法是這樣的:

bool valueIsNull; 
int value; 

query = "SELECT * FROM table WHERE field = ?"; // <-- this does not work 
statement st = sql.prepare(query); 
st.bind(0, value, valueIsNull); // <-- this works 

顯然,這是行不通的。但是有沒有一種乾淨的方式來處理這個問題?

我不認爲它很重要,但我使用C++,cppdb和postgresql。

+1

我沒有看到你的第一個或第二個例子沒有錯。 – mellamokb 2011-05-12 18:40:49

+0

@mellamokb:我知道這兩個例子的工作,但我的問題是,在第一個例子中,查詢在兩種情況下不同,所以如果我想重複使用預準備語句,它會增加更多的複雜性。 (特別是當有更多的參數可能是NULL)。在第二種情況下,SQL更復雜,我必須將同一個變量綁定兩次。對於較大的查詢,我發現它變得混亂和模糊。 – rve 2011-05-12 20:39:30

回答

5

PostgreSQL的(但我相信不是標準),可以使用

SELECT * from some_table where field IS NOT DISTINCT FROM ?; 

IS NOT DISTINCT FROM,不像平原=,當雙方都是NULL時爲真。

+0

問題在於,它不會在'field'上使用索引。 – 2011-05-12 20:22:05

+0

下次我應該首先檢查Google。 'IS [NOT] DISTINCT FROM'是標準的SQL,儘管我沒有檢查哪些DB(Postgres除外)知道支持它。 – 2011-05-12 20:22:26

+0

@Denis,我不明白爲什麼會如此。 NULL值是可索引的。 – 2011-05-12 20:24:13

3

正如您所指出的,主要的問題是:

SELECT * FROM table WHERE field = ? OR (? IS NULL AND field IS NULL) 

是,它實際上是需要綁定兩個參數。

讓您可以與一個(應該是相當便攜)構建,如:

SELECT * 
FROM table 
INNER JOIN (SELECT ? AS param1 /* FROM DUAL */) AS params 
    ON 1 = 1 
WHERE field = param1 
    OR COALESCE(param1, field) IS NULL 
+0

+1雖然便攜式,但不* sargable * – Matthew 2011-05-12 20:33:36

+0

我喜歡這一個,因爲它是便攜式。 – rve 2011-05-15 13:44:38