当前位置:  开发笔记 > 数据库 > 正文

在T-SQL中使用任意数量的参数

如何解决《在T-SQL中使用任意数量的参数》经验,为你挑选了1个好方法。

是否可以创建一个参数化的SQL语句,该语句将采用任意数量的参数?我试图允许用户根据多个关键字过滤列表,每个关键字用分号分隔.因此,输入将类似于"Oakland; City; Planning",WHERE子句将出现与下面相同的内容:

WHERE ProjectName LIKE '%Oakland%' AND ProjectName Like '%City%' AND ProjectName Like '%Planning%'

使用连接创建这样的列表真的很容易,但由于SQL注入漏洞,我不想采用这种方法.我有什么选择?我是否创建了一堆参数,希望用户不要尝试使用我定义的更多参数?或者有没有办法安全地创建参数化SQL?

性能不是什么大问题,因为该表现在只有大约900行,并且不会很快增长,可能每年50到100行.



1> Kevin Fairch..:

一个基本的概念验证......实际代码会少一些,但由于我不知道你的表/字段名称,这是完整的代码,所以任何人都可以验证它的工作原理,调整它等等.

--Search Parameters

DECLARE @SearchString VARCHAR(MAX)
SET @SearchString='Oakland;City;Planning' --Using your example search
DECLARE @Delim CHAR(1)
SET @Delim=';' --Using your deliminator from the example

--I didn't know your table name, so I'm making it... along with a few extra rows...

DECLARE @Projects TABLE (ProjectID INT, ProjectName VARCHAR(200))
INSERT INTO @Projects (ProjectID, ProjectName) SELECT 1, 'Oakland City Planning'
INSERT INTO @Projects (ProjectID, ProjectName) SELECT 2, 'Oakland City Construction'
INSERT INTO @Projects (ProjectID, ProjectName) SELECT 3, 'Skunk Works'
INSERT INTO @Projects (ProjectID, ProjectName) SELECT 4, 'Oakland Town Hall'
INSERT INTO @Projects (ProjectID, ProjectName) SELECT 5, 'Oakland Mall'
INSERT INTO @Projects (ProjectID, ProjectName) SELECT 6, 'StackOverflow Answer Planning'

--*** MAIN PROGRAM CODE STARTS HERE ***

DECLARE @Keywords TABLE (Keyword VARCHAR(MAX))

DECLARE @index int 
SET @index = -1 

--Each keyword gets inserted into the table
--Single keywords are handled, but I did not add code to remove duplicates
--since that affects performance only, not the result.

WHILE (LEN(@SearchString) > 0) 
  BEGIN  
    SET @index = CHARINDEX(@Delim , @SearchString)  
    IF (@index = 0) AND (LEN(@SearchString) > 0)  
      BEGIN   
        INSERT INTO @Keywords VALUES (@SearchString)
          BREAK  
      END  
    IF (@index > 1)  
      BEGIN   
        INSERT INTO @Keywords VALUES (LEFT(@SearchString, @index - 1))   
        SET @SearchString = RIGHT(@SearchString, (LEN(@SearchString) - @index))  
      END  
    ELSE 
      SET @SearchString = RIGHT(@SearchString, (LEN(@SearchString) - @index)) 
END


--This way, only a project with all of our keywords will be shown...

SELECT * 
FROM @Projects
WHERE ProjectID NOT IN (SELECT ProjectID FROM @Projects Projects INNER JOIN @Keywords Keywords ON CHARINDEX(Keywords.Keyword,Projects.ProjectName)=0)

我决定将几个不同的答案混合成一个:-P

这假设您将传递一个分隔的搜索关键字字符串列表(通过@SearchString传入)作为VARCHAR(MAX),实际上 - 您不会遇到关键字搜索的限制.

每个关键字都从列表中分解出来并添加到关键字表中.您可能希望添加代码以删除重复的关键字,但在我的示例中不会受到影响.效果稍差,因为我们只需要为每个关键字评估一次,理想情况下.

从那里,任何不属于项目名称的关键字都会从列表中删除该项目 ...

因此,搜索"奥克兰"给出了4个结果,但"奥克兰;城市;规划"只给出了1个结果.

您也可以更改分隔符,因此它可以使用空格而不是分号.或者无论你的船漂浮......

此外,由于连接而不是动态SQL,它不像您担心的那样冒着SQL注入的风险.

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有