2009-11-05 120 views
3

我創建了一個按姓氏返回申請人列表的過程。我有一個問題,搜索姓有撇號的申請人(例如O'Connor)。你能幫尋找那些申請人:將撇號添加到姓氏搜索

下面是我的查詢碼:

if Rtrim(@FirstName) <> '' 
begin 
    If(Len(@FirstName) < 30) and (CharIndex('%', @FirstName) = 0) and @FirstName != '' 
     Set @FirstName = char(39) + @FirstName + '%' + char(39) 
end 

if Rtrim(@LastName) <> '' 
begin 
    If(Len(@LastName) < 60) and (CharIndex('%', @LastName) = 0) and @LastName != '' 
    Set @LastName = Char(39) + @LastName + '%' + char(39) 
end 

#At the end - --Now build dinamically the filter base on input parameters 
if Rtrim(@FirstName) <> '' 
    select @Where = @Where + ' and a.FirstName like '+ Rtrim(@FirstName) 

if Rtrim(@LastName) <> '' 
    select @Where = @Where + ' and a.LastName like '+ Rtrim(@LastName) 
+1

你究竟在做什麼*做*?您似乎在構建動態SQL字符串,但*爲什麼*?此外,還有更好更安全的方法來處理動態SQL。 – Tomalak

回答

2

撇號使用雙引號T-SQL字符串中逃了出來,例如

SELECT * FROM sometable where LastName LIKE '%''%' 

注意,從那些可能包含撇號的字符串組裝動態SQL語句的組合是因爲SQL injection attacks風險非常危險。一個普通的用戶可能有一個像O'Connor這樣的名字,但是一個精明的攻擊者可能會選擇一個像名字一樣的名字,如"O'; TRUNCATE TABLE Customers; --",這可能會清除數據。

至少,如果您從字符串動態組裝SQL語句,則應在將該字符串注入SQL之前用雙撇號(例如REPLACE (@LastName, '''', ''''''))替換撇號。

但是,如果這些字符串來自用戶,則應該考慮使用參數化查詢,而不是通過使用SQL和參數字符串進行字符串連接來手動組裝SQL查詢。參數化意味着SQL客戶端API和/或服務器負責將參數轉換爲「安全」字符串。這是防止SQL注入攻擊的最佳防禦措施。看看這個Jeff Atwood blog post關於這方面的更多細節。

0

喜歡的東西:

... 
select @Where = @Where + ' and a.LastName like ' + Replace(Rtrim(@LastName), '''', '''''') 
... 

(是的,我知道,這些都是很多的報價,但很有效。)

,你需要在像 'X'語法的詳細報價:

select @Where = @Where + ' and a.LastName like ''' + Replace(Rtrim(@LastName), '''', '''''') + '''' 

(是的,越來越多的引號)

日將生成正確的:

and a.LastName 'like o''conor' 
+0

我試過你給了我什麼......但是當我執行過程時出現錯誤.. - select @Where = @Where +'and a.LastName like'+ Rtrim(@LastName) select @ Where'= @Where +'and a.LastName like'+ Replace(Rtrim(@LastName),'''','''''') 服務器:消息170,級別15,狀態1,行1 行1:'O'附近的語法錯誤。 – user203671

+0

我編輯了一些更多的引號。愛SQL。 –

2

您的代碼看起來像您試圖構建動態SQL WHERE子句。在那裏停下來扔掉它,你的方法很危險,容易出錯。

您可能要沿着這不是線做一些事情:

/* declare a few test variables */ 
DECLARE @FirstName varchar(30) 
DECLARE @LastName varchar(60) 
SET @FirstName = 'First''Name' 
SET @LastName = 'Last''Name' 

/* these variables are for dynamic SQL execution */ 
DECLARE @IntVariable int 
DECLARE @SQLString nvarchar(500) 
DECLARE @ParmDefinition nvarchar(500) 

/* define a paramertized SQL query */ 
SET @SQLString = 
N'SELECT 
    UserId 
    FROM 
    UserTable 
    WHERE 
    LastName LIKE ''%'' + @ln + ''%'' 
    AND FirstName LIKE ''%'' + @fn + ''%'' 
    ' 

/* define the used parameters and their types */  
SET @ParmDefinition = N'@ln varchar(30), @fn varchar(60)' 

/* execute dynamic SQL, syntax- and code-injection safely */ 
EXECUTE sp_executesql @SQLString, @ParmDefinition, 
         @ln = @LastName, @fn = @FirstName 

請務必閱讀MSDN on sp_executesql更多解釋&樣本。