2013-03-11 76 views
0

我需要寫這是基於不同的過濾器 如標題,描述,分類,作者,語言&日期MS SQL查詢高級搜索

我需要這個查詢作爲存儲高級搜索一個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; } 
+1

我想你可以從閱讀本文獲益:[T-SQL中的動態搜索條件](http://www.sommarskog.se/dyn-search-2008.html) – 2013-03-11 06:27:32

+0

選中此項:http:// stackoverflow。 com/questions/263801/sql-server-dynamic-queries – 2013-03-11 06:33:48

+1

不能強調閱讀由@MikaelEriksson鏈接的文章的重要性 – 2013-03-11 08:41:46

回答

2

您可以使用您在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注入來驗證它在你的C#代碼傳遞變量SQL-Server之前。

另一種方法(或可能最適用於猜測)不是使用「EXEC」命令,而是使用名爲「sp_executesql」的內置存儲過程。其中

詳細信息可以在這裏找到:http://msdn.microsoft.com/en-gb/library/ms188001.aspx 如何使用在這裏詳細描述:http://msdn.microsoft.com/en-gb/library/ms175170(v=sql.105).aspx

你必須建立自己的SQL略有不同,並傳遞參數到存儲過程以及該@ SQL。

+0

我已經實現了類似的方法來解決這個問題,我知道這種方法中的sql注入漏洞。我使用了我作爲答案發布的相同方法。我同意你關於使用強大驗證需要處理的漏洞。如果您能提出任何其他更安全的方法,我將不勝感激。 – Learning 2013-03-12 04:15:02

+0

我也注意到在你的方法中,你已經使用了'Varchar()'數據類型的每個變量,這可以使T-SQL內部的驗證更加困難,並且如果將Integer變量定義爲'INT',那麼你會得到轉換錯誤'轉換失敗時轉換varchar value'。我無法找到原因,但驗證可以通過代碼處理,以便得到一個乾淨的SQL查詢。如果sql注入附加有十六進制代碼就是他們稱之爲SQL查詢與十六進制...我不知道如何過濾如果他們插入十六進制代碼。這是不是一個問題? – Learning 2013-03-12 04:30:51

+0

我已經更新了我的答案,並詳細介紹瞭如何防範SQL注入。這主要是使用「sp_executesql」而不是「EXEC」。 – 2013-03-12 07:53:08