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)
4

3 回答 3

2

撇号在 T-SQL 字符串中使用双撇号进行转义,例如

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

请注意,从可能包含撇号的字符串组合动态 SQL 语句的组合是非常危险的,因为存在SQL 注入攻击的风险。普通用户可能有像 O'Connor 这样的名字,但精明的攻击者可能会选择一个"O'; TRUNCATE TABLE Customers; --"可以擦除数据的“名字”。

至少,如果您是从字符串动态组装 SQL 语句,则应该REPLACE (@LastName, '''', '''''')在将该字符串注入 SQL 之前将撇号替换为双撇号(例如 )。

但是,如果这些字符串来自用户,您应该真正考虑使用参数化查询,而不是通过字符串与 SQL 和参数字符串连接来手动组装 SQL 查询。参数化意味着 SQL 客户端 API 和/或服务器负责将参数转换为“安全”字符串。这是对 SQL 注入攻击的最佳防御。请查看此Jeff Atwood 博客文章,了解有关此内容的更多详细信息。

于 2009-11-05T16:32:54.567 回答
2

您的代码看起来像是在尝试构建动态 SQLWHERE子句。把它停在那里扔掉,你的方法很危险而且容易出错。

您可能想要按照以下方式做一些事情:

/* 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 以sp_executesql获取更多说明和示例。

于 2009-11-05T16:58:53.260 回答
0

就像是:

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

(是的,我知道,这些引用很多,但它有效。)

并且您需要在like ' x '语法中使用更多引号:

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

(是的,越来越多的报价)

这将生成正确的:

and a.LastName 'like o''conor'
于 2009-11-05T16:46:14.900 回答