【问题标题】:MS SQL query for advance search [duplicate]用于高级搜索的 MS SQL 查询 [重复]
【发布时间】:2013-03-12 15:51:47
【问题描述】:

我需要为基于不同过滤器的高级搜索编写一个 ms sql 查询 比如标题、描述、类别、作者、语言和日期

我需要将此查询作为存储过程,但我不确定如果 CatID = 0、WriterID = 0 等,我如何构建查询。我可以使用IF Statement 在 c# (ASP.Net) 中轻松构建此查询并传递整个查询,但我不确定如何将其构建为 T-SQL 或存储过程

DECLARE @keyword nvarchar(300)
DECLARE @CatID int
DECLARE @WritterID int
DECLARE @IssueID int
DECLARE @sDate date
DECLARE @eDate date
DECLARE @LangID int
    SET @keyword = 'xyz';
    SET @CatID = 1;
    SET @WritterID = 1;
    SET @IssueID = 1;
    SET @sDate = '1/01/2012';
    SET @eDate = '1/01/2013';
    SET @LangID = 1


SELECT ArticleID,ArticleTitle,ArticleCategoryID,ArticleAuthorID,IssueID,ArticlePublishDate FROM art_Articles
    WHERE  ArticleTitle LIKE '%'+ @keyword +'%' 
    OR   ArticleDesc LIKE '%'+ @keyword +'%' 

C# 中的代码示例

    strSql = "SELECT ArticleID, ArticleTitle, ArticleDesc, ArticlePublishDate FROM art_Articles WHERE ";
    strSql += "( (ArticleVisible = 1 AND ArticleActive =1 AND LanguageID =" + LangID + " ))";
        if (CatID > 0)
        { strSql += " AND  ArticleCategoryID ="+ CatID; }
        if (WriterID > 0)
        { strSql += " AND  ArticleAuthorID ="+ WriterID; }

【问题讨论】:

标签: sql-server sql-server-2008 tsql


【解决方案1】:

您可以像在 C# 代码中一样在 SqlServer 中构建 SQL。

声明一个文本变量并使用它来连接你想要的 SQL。

这称为动态 SQL。

然后您可以使用“EXEC”命令执行此代码

例子:


DECLARE @SQL VARCHAR(100)
DECLARE @LangID VARCHAR(20)
DECLARE @CatID VARCHAR(20)
DECLARE @WriterID VARCHAR(20)

SET @SQL = 'SELECT ArticleID, ArticleTitle, ArticleDesc, ArticlePublishDate FROM art_Articles WHERE '

SET @SQL = @SQL + '( (ArticleVisible = 1 AND ArticleActive =1 AND LanguageID =' + @LangID

IF (@CatID > 0)
    SET @SQL = @SQL + ' AND  ArticleCategoryID =' + @CatID

IF (@WriterID > 0)
    SET @SQL = @SQL + ' AND  ArticleAuthorID ='+ @WriterID

EXEC (@SQL)

但是,使用此方法时您真正应该注意的是一个称为“SQL 注入”的安全问题。

你可以在这里阅读: http://msdn.microsoft.com/en-gb/library/ms161953(v=sql.105).aspx

防止 SQL 注入的一种方法是在将变量传递给 SQL-Server 之前在 C# 代码中对其进行验证。

另一种方法(或者可能在推测中最好使用)是使用名为“sp_executesql”的内置存储过程,而不是使用“EXEC”命令。

详情请见:http://msdn.microsoft.com/en-gb/library/ms188001.aspx 详细使用方法在这里:http://msdn.microsoft.com/en-gb/library/ms175170(v=sql.105).aspx

您必须稍微不同地构建您的 SQL,并将您的参数传递给存储过程以及 @SQL。

【讨论】:

  • 我已经实施了类似的方法来解决这个问题,并且我知道这种方法中存在 sql 注入漏洞。我使用了与我发布的答案相同的方法。我同意你关于需要使用强验证来处理的漏洞。如果您能建议任何其他更安全的方法,我将不胜感激。
  • 我还注意到,在您的方法中,您对每个变量都使用了 Varchar() 数据类型,这会使 T-SQL 内部的验证变得困难,如果您将整数变量定义为 INT,那么您会收到转换错误 @987654328 @。我无法找到原因,但可以通过代码处理验证,以便获得干净的 sql 查询。如果 sql injection attach 具有 HEX 代码,将很难处理 sql 注入,因为他们称之为使用 HEX 的 SQL 查询......我不知道如果他们插入 HEX 代码如何过滤。这是一个不同的问题吗?
  • 我更新了我的答案,提供了更多关于如何防范 SQL 注入的细节。这主要是使用“sp_executesql”而不是“EXEC”。
  • 这就是我正在做的事情,我使用这个链接来构建我的 sql codeproject.com/Articles/20815/…
  • 我相信这是最好的方法。它是否涵盖了您不确定的所有内容?您还有其他问题吗?
【解决方案2】:

我在 codeproject.com 上为存储过程中的动态 sql 查询找到了很好的解决方案

http://www.codeproject.com/Articles/20815/Building-Dynamic-SQL-In-a-Stored-Procedure

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 2015-06-09
    • 1970-01-01
    相关资源
    最近更新 更多