"AND TT.[_TYPE] = CASE WHEN " + String.IsNullOrEmpty(lstTypeSearch.SelectedItem) ?
DBNull.Value} +
" IS NULL THEN TT.[_TYPE] ELSE " + lstTypeSearch.SelectedItem + " END ";
以上是我查询的伪方面。
我需要对null的listbox项进行验证,然后设置为DBNull.Value,它将在SQL Query中传递给CASE WHEN。
有没有更好的方法来实现这一目标?我收到大量的String to Bool,Null to String转换错误...
此外,有没有将DBNull.Value作为参数传递到数据访问层?
编辑:原始查询属于静态类。
public static readonly string SqlGetItemsBy_Number_Capacity_Type =
"SELECT TT.[_NUMBER], " +
"TT.[CAPACITY], " +
"TT.[_TYPE], " +
"TS.[SESSIONE] " +
"FROM [ITEMS] AS TT, //some code
"WHERE //some code
"AND TT.[_TYPE] = CASE WHEN @Type IS NULL THEN TT.[_TYPE] ELSE @Type END";
如果我在SQL Server中运行相同的查询,它可以正常工作。
SELECT //some code
AND [_TYPE] = CASE WHEN NULL IS NULL THEN [_TYPE] ELSE @TYPE END
最后:我决定使用SQL Append并跟随验证/设置参数。
string paramAppend;
var bld = lstTypeSearch.SelectedItem;
if (bld != null)
{
paramAppend = "AND TT.[_TYPE] = " + lstTypeSearch.SelectedItem.ToString();
}
else
paramAppend = "";
答案 0 :(得分:3)
看起来lstTypeSearch
这里代表一个列名(因此参数化:不是一个选项),所以我要说的第一件事是:确保你列出白名单。而不是试图一气呵成,将两种情况分开:
if(string.IsNullOrEmpty(lstTypeSearch.SelectedItem))
{
// nothing to check?
}
else
{
CheckValidColumn(lstTypeSearch.SelectedItem); // throws if white-list fails
sql.Append(" AND TT.[_TYPE] = [") // should probably add table alias
.Append(lstTypeSearch.SelectedItem)
.Append("]");
}
如果我误解了,这不是一个列,那么只需参数化:
if(string.IsNullOrEmpty(lstTypeSearch.SelectedItem))
{
// no restriction?
}
else
{
sql.Append(" AND TT.[_TYPE] = @type");
cmd.Parameters.AddWithValue("type", lstTypeSearch.SelectedItem);
}
// ...
cmd.CommandText = sql.ToString();
答案 1 :(得分:2)
首先,您应该使用参数,除非希望暴露于潜在的SQL注入威胁。
其次,如果要在代码中动态构建sql,更好的方法是仅在lstTypeSearch.SelectedItem不是空字符串或null时才添加sql条件。类似的东西:
sSql = "your sql query";
if(!String.IsNullOrEmpty(lstTypeSearch.SelectedItem)) {
sSql += "TT.[_TYPE] = '" + lstTypeSearch.SelectedItem + "'";
}
sSql += ";"
btw,如果SelectedItem有一个只包含空格的字符串怎么办?考虑将String.IsNullOrEmpty替换为String.IsNullOrWhiteSpace。
答案 2 :(得分:2)
如果为null,则在SQL中将其提供给案例,因此它将返回所有数据。
我解释这意味着如果没有指定值,则返回所有行,否则按该值过滤。
我假设lstTypeSearch.SelectedItem
是您的价值而且它是string
。如果没有,则抛出或挖出字符串值。
command.CommandText =
"SELECT * FROM TT WHERE @SelectedItem IS NULL OR TT.[_TYPE] = @SelectedItem";
var selectedItem = (string) lstTypeSearch.SelectedItem;
command.Parameters.AddWithValue("@SelectedItem",
String.IsNullOrEmpty(selectedItem) ? (object) DBNull.Value : selectedItem);
using (var dataReader = command.ExecuteReader())
{
...
}
答案 3 :(得分:2)
通过编辑,您应该能够用:
替换最后一行AND (@Type IS NULL OR TT.[_TYPE] = @Type)
更清楚,虽然坦率地说它不能用于优秀的查询缓存计划使用或优化; IMO最好只是编写正确的SQL。
至于传递价值:
object value = string.IsNullOrEmpty(lstTypeSearch.SelectedItem)
? (object)DBNull.Value : (object)lstTypeSearch.SelectedItem;
// ...
cmd.Parameters.AddWithValue("Type", value);