Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL中搜索具有可选特殊字符的匹配项?_Sql_Search_Apostrophe - Fatal编程技术网

如何在SQL中搜索具有可选特殊字符的匹配项?

如何在SQL中搜索具有可选特殊字符的匹配项?,sql,search,apostrophe,Sql,Search,Apostrophe,我在使用的搜索查询中遇到了一个问题,我的数据中包含的名称和信息有各种形式的撇号(HTML编码的和实际的)。 例如,我想要一个替代方案: SELECT * FROM Customers WHERE REPLACE(LastName,'''','') LIKE Replace('O''Brien,'''','') 这只是一个例子,我想要的是一种方式,如果有人键入OBrien或O'Brien,这仍然有效,我需要替换字符的三个版本,并且数据源为feed,无法更改-可以对查询做什么来允许这种搜索工作。

我在使用的搜索查询中遇到了一个问题,我的数据中包含的名称和信息有各种形式的撇号(HTML编码的和实际的)。 例如,我想要一个替代方案:

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实体规范化。