当然,您可以在该 sql 中包含可选参数。
你这样做的方式?您不在 sql 中包含参数,然后仅根据需要添加参数!这样,您就不需要在作为条件的 sql 中的所有这些额外条件,然后还需要对 @Param = null 的测试。
因此,假设我可以搜索城市或城市 + 酒店名称。并让我们折腾 [x] 仅搜索活动酒店。或者我们只搜索 Hotelname。或所有 3 个值!
正如您注意到的那样,这变成了一个只需要处理 3 个选择(6 个可能的排列)的参数集。我只能想象如果你有 5 或 6 个可能的和可选的值,这会变得多么糟糕。
那么,简单的解决方案?好吧,我们将 sql 拆分为基本查询,然后动态添加参数。我们仍然想要(并获得)强类型参数检查,从而获得 sql 注入保护,这当然是这里的一个重要目标。
因此我们有这样的设置:
然后搜索会这样做:
public void loadgrid()
{
string strSQL;
string strWhere;
strSQL = "select ID, FirstName, LastName, HotelName, City, Province from tblHotels";
strWhere = "";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, new SqlConnection(My.Settings.Test3)))
{
if (txtHotelName.Text != "")
{
// search for hotel name
strWhere = "(HotelName = @HotelName)";
cmdSQL.Parameters.Add("@HotelName", SqlDbType.NVarChar).Value = txtHotelName.Text;
}
if (txtCity.Text != "")
{
if (strWhere != "")
strWhere += " AND ";
strWhere += "(City = @City)";
cmdSQL.Parameters.Add("@City", SqlDbType.NVarChar).Value = txtCity.Text;
}
if (chkOnlyActive.Checked == true)
{
if (strWhere != "")
strWhere += " AND ";
strWhere += strWhere + "(HotelActive = @Active)";
cmdSQL.Parameters.Add("@Active", SqlDbType.Bit).Value = 1;
}
if (strWhere != "")
cmdSQL.CommandText = strSQL + " WHERE " + strWhere;
cmdSQL.Connection.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader);
ListView1.DataSource = rstData;
ListView1.DataBind();
}
}
所以请注意我们如何简单地构建 where 子句。而且您注意到没有什么可以阻止我们更改 sql 命令文本 - 而且我们也 100% 能够动态添加参数(添加它们不会强制检查 sql - 仅在执行时。
结果呢?我们可以再添加 5 个标准。它们是可选的,它们不需要我们使用我们可能不想使用甚至不需要的大量参数进行巨大的长 sql 查询。
如上所示,我们永远不会将用户输入串联起来——它们总是只与参数值一起使用。
那么,对于任何文本框、复选框、组合框或其他什么?当它们没有填写时,我们只是忽略它们。因此它们都是可选的,并且在我们的代码中被忽略了。因此,上述设置可以让我们轻松添加 2 或 5 个更多可选参数。
注意上面,我们总是“检查” where 子句是否已经有一些值——如果是,那么我们在前面添加“AND”子句。我们可以在这里使用“OR”,但这取决于您想要的搜索类型。