如何在SQL中搜索具有可选特殊字符的匹配项?
我在使用的搜索查询中遇到了一个问题,我的数据中包含的名称和信息有各种形式的撇号(HTML编码的和实际的)。 例如,我想要一个替代方案:如何在SQL中搜索具有可选特殊字符的匹配项?,sql,search,apostrophe,Sql,Search,Apostrophe,我在使用的搜索查询中遇到了一个问题,我的数据中包含的名称和信息有各种形式的撇号(HTML编码的和实际的)。 例如,我想要一个替代方案: SELECT * FROM Customers WHERE REPLACE(LastName,'''','') LIKE Replace('O''Brien,'''','') 这只是一个例子,我想要的是一种方式,如果有人键入OBrien或O'Brien,这仍然有效,我需要替换字符的三个版本,并且数据源为feed,无法更改-可以对查询做什么来允许这种搜索工作。
SELECT * FROM Customers WHERE REPLACE(LastName,'''','')
LIKE Replace('O''Brien,'''','')
这只是一个例子,我想要的是一种方式,如果有人键入OBrien或O'Brien,这仍然有效,我需要替换字符的三个版本,并且数据源为feed,无法更改-可以对查询做什么来允许这种搜索工作。我有一些项目的名称是以这种方式工作的,这些项目目前有许多嵌套的替换函数,而且似乎找不到以这种方式工作的项目,因为这样更有效。
如果有帮助的话,我正在使用MS SQL 2000和ASP
编辑 这是一个需要匹配O'Brien或OBrien的查询,这个查询可以做到这一点,但效率太低-它由另一个查询项名称和FirstName(可选)连接以进行匹配
SELECT * FROM Customers
WHERE
REPLACE(REPLACE(REPLACE(LastName,''',''),''',''),'''','')
LIKE
REPLACE(REPLACE(REPLACE('%O'Brien%',''',''),''',''),'''','')
你可以试试这个:
SELECT *
FROM Customers
WHERE LastName LIKE Replace('O''Brien,'''','%')
这应该允许它使用索引,因为您没有修改原始列。使用参数,而不是在代码中构建查询 如果使用ADO,可以使用如下语法:
Dim cmd, rs, connect, intNumber
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = "your connectionstring"
cmd.CommandText = "SELECT * FROM Customers WHERE LastName LIKE @LastName"
cmd.Parameters.Append cmd.CreateParameter("@LastName",,,,"O'Brien")
Set rs = cmd.Execute
这将执行查询并插入为数据库正确格式化的字符串O'Brien
使用参数可以确保所有值的格式正确,还可以防止sql注入攻击。对于纯sql,转义是完全不必要的
SELECT * FROM Customers WHERE LastName = 'O''Brien'
如果您想保持正确并在SQL中执行此操作,这可能是您所能做的最好的方法
SELECT * FROM Customers WHERE
LastName LIKE 'O%Brien' AND
REPLACE(LastName,'''','') LIKE 'O''Brien'
由于选择性差,有时仍会进行表扫描
第一个where的原因是尝试使用现有索引。
第二个匹配的原因是为了确保像ObbBrien这样的姓氏不匹配
当然,最好的办法是不需要丑陋的替代品。这可以通过在应用程序中存储一个额外的干净的lastname列来实现。或者在触发器中。或者在索引视图中 请注意,在这个特定的实例中,它很可能会选择完全扫描,因为它可能认为从索引中提取所有以O开头的记录太昂贵。我同意这可能是你在类似的查询中能做的最好的了,所以,对于某些输入来说,这是非常危险的,例如:OohnoitsBrien也会匹配!!!为什么要在数据库中存储HTML实体,而不是实际字符?HTML实体随数据源而来,因为它来自以这种方式存储数据的外部源,也许这可以用实际的字符来代替——这可以解决多次替换的需要。数据库中没有HTML可以防止各种令人讨厌的麻烦,不仅仅是这个。如果您可以对此做些什么,请在存储数据之前将数据中的HTML实体规范化。