2011-12-20 58 views
0

假設我正在查詢一個表,而null可能是要查找的值之一。設置爲這樣的查詢正確的方式來處理參數化查詢中的空值?

command.CommandText = "select * from People where Saluation = @salutation"; 

if(salutation != null) command.Parameters.AddWithValue("@salutation", salutation); 
else command.Parameters.AddWithValue("@salutation", DBNull.Value); 

當稱呼爲空時不會返回任何結果。所以我傾向於這樣做,但我覺得很難看:

string whereClause; 
if(!string.IsNullOrEmpty(salutation)) 
{ 
    whereClause = "Salutation = @salutation"; 
    command.Parameters.AddWithValue("@salutation", salutation); 
} 
else whereClause = "Salutation is null"; 

command.CommandText = "select * from People where " + whereClause; 

是否有更正確的方法?

回答

3

我可能會避免串聯來建立你的where子句。您可以將您的sql更改爲以下內容。可能會打開自己的SQL注入攻擊。

command.CommandText = "select * from People where (@salutation is null and salutation is null) or Saluation = @salutation"; 
+1

如果未連接外部字符串,串聯不會造成注入漏洞。 – 2011-12-20 04:26:57

+0

非常真實,它更容易陷入壞習慣。 – 2011-12-20 08:14:06

+0

當@salutation爲空時,原始版本返回所有行 - 它應該是(@salutation爲null,salutation爲null)。我剛發佈了一個修改,一旦通過同行評審就會接受。 – 2011-12-20 15:44:39

0

也許你可以使用COALESCE函數,將默認值設置爲第二個參數。

1

您可以添加一個額外的參數來指定是否要返回空值,並稍微修改您的查詢。

要使用你的例子:

command.CommandText = "select * from People where ((@IsNull_Salutation = 1 AND Salutation IS NULL) OR (Saluation = @Salutation))"; 

command.Parameters.AddWithValue("Salutation", salutation ?? (object)DBNull.Value); 
command.Parameters.AddWithValue("IsNull_Salutation", (salutation == null) ? 1 : 0); 

這可以讓你保持你的查詢完全參數化。如果您決定要停止返回空值,則只需將您傳入的值更改爲IsNull_Salutation參數。

從內存來看,這與SqlCommandBuilder類在其自動生成的insert/update/delete查詢中如何處理空值類似。

-1
command.CommandText = "select * from People where Saluation "; 
command.CommandText += salutation != null ? ("= " + salutation) : "is NULL"; 
+4

我只會傳遞我最喜歡的稱呼:'1; drop table people;':) – MatthewKing 2011-12-20 03:27:26

+2

-1不使用參數化查詢並允許Joviee銷燬Soylent Green。 – 2011-12-20 03:44:30

0

保持簡單: 只需使用這樣的WHERE子句

WHERE @field IS NULL OR field = @field 

將SQL Server足夠聰明,使用基於@field參數的值處於正常的狀態。 在這種情況下重要的事情 - 不要在查詢中更改參數值,然後纔會在SELECT stmt中使用它。