我正在研究将要查询我们员工数据库的工作申请.最终用户希望能够根据标准名称/部门标准进行搜索,但他们也希望能够灵活地查询所有在健康部门工作的名字为"James"的人.我想要避免的一件事是简单地让存储过程获取参数列表并生成要执行的SQL语句,因为这将在内部级别打开SQL注入的大门.
可以这样做吗?
虽然COALESCE
技巧很好,但我首选的方法是:
CREATE PROCEDURE ps_Customers_SELECT_NameCityCountry @Cus_Name varchar(30) = NULL ,@Cus_City varchar(30) = NULL ,@Cus_Country varchar(30) = NULL ,@Dept_ID int = NULL ,@Dept_ID_partial varchar(10) = NULL AS SELECT Cus_Name ,Cus_City ,Cus_Country ,Dept_ID FROM Customers WHERE (@Cus_Name IS NULL OR Cus_Name LIKE '%' + @Cus_Name + '%') AND (@Cus_City IS NULL OR Cus_City LIKE '%' + @Cus_City + '%') AND (@Cus_Country IS NULL OR Cus_Country LIKE '%' + @Cus_Country + '%') AND (@Dept_ID IS NULL OR Dept_ID = @DeptID) AND (@Dept_ID_partial IS NULL OR CONVERT(varchar, Dept_ID) LIKE '%' + @Dept_ID_partial + '%')
这些类型的SP可以很容易地生成代码(并为表更改重新生成).
您有一些处理数字的选项 - 取决于您是否需要精确的语义或搜索语义.
实现此类搜索的最有效方法是使用存储过程.此处显示的语句创建一个接受所需参数的过程.如果未提供参数值,则将其设置为NULL.
CREATE PROCEDURE ps_Customers_SELECT_NameCityCountry @Cus_Name varchar(30) = NULL, @Cus_City varchar(30) = NULL, @Cus_Country varchar(30) =NULL AS SELECT Cus_Name, Cus_City, Cus_Country FROM Customers WHERE Cus_Name = COALESCE(@Cus_Name,Cus_Name) AND Cus_City = COALESCE(@Cus_City,Cus_City) AND Cus_Country = COALESCE(@Cus_Country,Cus_Country)
摘自本页:http://www.sqlteam.com/article/implementing-a-dynamic-where-clause
我以前做过.它运作良好.
Erland Sommarskog的文章T-SQL中的动态搜索条件是如何做到这一点的一个很好的参考.Erland提出了许多关于如何在不使用动态SQL(只是简单的IF块,OR,COALESCE等)的情况下执行此操作的策略,甚至列出了每种技术的性能特征.
如果您必须咬紧牙关并完成动态SQL路径,您还应该阅读Erland的动态SQL诅咒和祝福,并提供有关如何正确编写动态SQL的一些提示