4

我在一个非常简单的应用程序中使用 SqlDataSource。我允许用户通过 TextBoxes 为 SDS 的选择命令设置几个搜索参数,每个参数一个 TextBox(想想 txtFirstName、txtLastName 等)。我计划使用按钮单击事件处理程序来设置 SqlDataSource 的 SelectCommand 属性,默认情况下将返回所有记录(出于我的目的)。我想根据用户是否在我的任何文本框中输入搜索条件来优化此选择命令以添加一个或多个 WHERE 子句。

如果我不清楚,例如:

默认情况下,我的 SqlDataSource 的 SelectCommand 属性将是这样的:

SELECT * FROM MyTable

如果用户在 txtFirstName 中输入“Bob”,我希望 SelectCommand 属性看起来像这样:

SELECT * FROM MyTable WHERE [FirstName]='Bob'

如果用户在 txtLastName 中输入“Jones”,我希望 SelectCommand 属性看起来像这样:

SELECT * FROM MyTable WHERE [FirstName]='Bob' AND [LastName]='Jones'

我的问题:
有没有一种方法可以动态创建这些 WHERE 子句,而我不必测试空的 TextBox 并手动构建 WHERE 子句?

我的小应用程序只有三个参数,所以强行通过它不会很痛苦,但我想知道是否有更简单的方法可以做到这一点,而且将来我可能需要添加更多参数。另外,我可能想添加通配符搜索。

4

4 回答 4

4

如果您使用的是 SqlDataSource 控件,并且您的参数值来自页面控件,则可以提供 ControlParameters 并使用带有短路参数的静态 where 子句。这可能只是快速敲出一些代码的门票。

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:AdventureworksConnectionString %>"
    SelectCommand=" SELECT FirstName, LastName, Age
                    FROM Contacts 
                    WHERE (FirstName=@FirstName or @FirstName = '')
                    AND (LastName = @LastName or @LastName = '' 
                    AND (Age = @Age or @Age = 0" >
        <SelectParameters>
            <asp:ControlParameter Name="FirstName" ControlID="TBFirstName" Type="String" />
            <asp:ControlParameter Name="LastName" ControlID="TBLastName" Type="String" />
            <asp:ControlParameter Name="Age" ControlID="TBAge" Type="Int16" />
        </SelectParameters>
    </asp:SqlDataSource>
于 2012-04-17T19:41:30.067 回答
2

正如您所说,构造该查询并不难,因为您总是在 where 子句中对字段进行与运算。

请注意,如果您这样做,请不要格式化字符串。使用 SqlParameters 避免 SQL 注入:http ://en.wikipedia.org/wiki/SQL_injection

因此,您可以从 WHERE 开始,对于每个具有值的文本框,附加 [(fieldName)] = @(fieldname) 并绑定该 sql 参数。

请参阅:http: //msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter.aspx

如果您愿意使用 Linq to SQL 或实体框架,请参阅此谓词构建器:http ://www.albahari.com/nutshell/predicatebuilder.aspx

于 2012-02-09T00:23:48.133 回答
2

您可以设置ConvertEmptyStringToNull="false"并执行以下操作:

SELECT * 
FROM MyTable 
WHERE [FirstName] = CASE @firstname WHEN '' THEN [FirstName] END AND 
    [LastName] = CASE @lastname WHEN '' THEN [LastName] END 

或者您可以设置 ConvertEmptyStringToNull="true" 并执行以下操作:

SELECT * 
FROM MyTable 
WHERE [FirstName] = ISNULL(@firstname, [FirstName]) AND 
    [LastName] = ISNULL(@lastname,[LastName])

在其中任何一个中,如果用户将文本框留空,CASEorISNULL语句会导致 where 语句的每个部分与自身进行比较,从而返回TRUE并生成相同的记录,就好像 where 子句的该部分根本不存在一样。这是一个很好且简单的解决方案,可以保持查询和参数静态并将逻辑推送到 SQL 端。

但是,与仅说"SELECT * FROM MyTable". 这些CASEISNULL操作不是免费的;)如果这是一个问题,Bryanmac 的解决方案是一个完全可以接受的解决方案。

于 2012-03-27T15:00:52.477 回答
0

您可以使用CancelSelectOnNullParameter=false本例所示

于 2012-02-09T00:30:54.237 回答