Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.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 server 使用CONTAINSTABLE在SQL Server全文搜索查询中转义符号_Sql Server_Tsql_Escaping_Full Text Search - Fatal编程技术网

Sql server 使用CONTAINSTABLE在SQL Server全文搜索查询中转义符号

Sql server 使用CONTAINSTABLE在SQL Server全文搜索查询中转义符号,sql-server,tsql,escaping,full-text-search,Sql Server,Tsql,Escaping,Full Text Search,我有一个非常特殊的病例。我的ASP.NET页面调用我们的一个存储过程,该存储过程对数据库执行全文搜索查询。一些常用的搜索字符串包括一个符号,因为我们产品的一些品牌(知名品牌也是)的名称中有一个& 事实证明,在某种情况下,除非我逃逸了符号(\&),否则我得不到结果,而在另一种情况下,只有逃逸了符号,我才得到结果 我不知道这是否相关,但(不给出品牌名称)一个以&b结尾,另一个以&c结尾 这些字符串(&b或&c)是否可能有自己的特殊含义?通过转义它们,我实际上是在向T-SQL传递一个特殊的字符串 编辑

我有一个非常特殊的病例。我的ASP.NET页面调用我们的一个存储过程,该存储过程对数据库执行全文搜索查询。一些常用的搜索字符串包括一个符号,因为我们产品的一些品牌(知名品牌也是)的名称中有一个
&

事实证明,在某种情况下,除非我逃逸了符号(
\&
),否则我得不到结果,而在另一种情况下,只有逃逸了符号,我才得到结果

我不知道这是否相关,但(不给出品牌名称)一个以
&b
结尾,另一个以
&c
结尾

这些字符串(
&b
&c
)是否可能有自己的特殊含义?通过转义它们,我实际上是在向T-SQL传递一个特殊的字符串

编辑

附加信息:经过进一步的测试,我证明错误在存储过程本身。用
&
\&
调用它会产生不同的结果

我将尝试发布存储过程的选定部分。我不会把它全部贴出来,因为大部分都不相关

vParamBuca
参数是导致故障的参数。值可以是
'word&letter'
word\&letter

SET @ricercaA = '''FORMSOF(INFLECTIONAL,"' +
    REPLACE(LTRIM(RTRIM(@vParamBuca)),' ', '") AND FORMSOF(INFLECTIONAL,"') + '")'''
然后使用变量
@ricercaA
创建查询字符串:

[...]
FROM Products AS FT_TBL
LEFT OUTER JOIN CONTAINSTABLE (Products, Sign1, '+ @ricercaA + ') AS ColSign1_0 ON FT_TBL.ID = ColSign1_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, ManufacturerAdditionalText, '+ @ricercaA + ') AS ColManufacturerAdditionalText_0 ON FT_TBL.ID = ColManufacturerAdditionalText_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, ManufacturerForSearch, '+ @ricercaA + ') AS ColManufacturer_0 ON FT_TBL.ID = ColManufacturer_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, TuttaLaRiga, '+ @ricercaA + ') AS ColTuttaLaRiga_0 ON FT_TBL.ID = ColTuttaLaRiga_0.[KEY]
[...]
编辑2

非常感谢@srutzky为我指明了正确的方向!与此同时,我还发现一个数据不一致,其中一个品牌的名称中有
&
被修改为没有
&
,而另一个没有被修改(底线是,我目前的问题是由这一点引起的:过去有人做了部分修复)

无论如何,回到正轨。现在我了解到
CONTAINSTABLE
函数中的
字符被视为逻辑AND(非位)


我仍然需要一个解决方案。给出了一个不适合我的解决方案(条件与我的不同)。如何执行
CONTAINSTABLE
搜索包含与的字符串?最好不必将符号转换为另一个安全字符?

您看到的奇怪行为很可能是由于and函数(与SQL Server的全文搜索功能一起使用)将符号(
&
)字符等效于
运算符。以下语句摘自
包含的
文档:

可以使用与符号(&)代替AND关键字来表示AND运算符

没有提到它有任何转义字符(反斜杠在SQL中通常不是转义字符)


更新

根据问题“编辑2”中现在提供的信息和其他研究,我想说,你不需要逃避任何事情。似乎将搜索短语放在双引号中(由于使用了
FORMSOF
)会将
&
视为文字或分词符,具体取决于
&
两侧的值。请尝试以下示例:

DECLARE @Term NVARCHAR(100);

SET @Term = N'bob&sally'; -- 48 rows
--SET @Term = N'bob\&sally'; -- 48 rows
--SET @Term = N'r&f'; -- 4 rows
--SET @Term = N'r\&f'; -- 24 rows

SET @Term = N'FORMSOF(INFLECTIONAL,"' + @Term + '")';

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1);
bob&sally
bob\&sally
的结果是相同的,并且在这两种情况下,
bob
sally
是分开的,从不组合成一个完全匹配的字符串

然而,
r&f
r\&f
之间的结果并不相同
r&f
仅被视为单个精确匹配字符串,因为
r
f
单独是未知单词。另一方面,在反斜杠中添加分隔两个字母,因为
\
是一个分词器,在这种情况下,您可以同时获得
r
f

鉴于您在更新中声明“数据不一致,其中一个名称中带有“&”的品牌被修改为没有“&”,而另一个没有”,我怀疑,当您没有添加
\
字符时,您会得到未修改的品牌(因为它与完整术语完全匹配)。但是,当您添加
\
字符时,您将获得修改后删除
&
的品牌,因为您现在正在搜索两个部分,每个部分都与该品牌名称匹配


我会修正数据的一致性:更新删除了
&
的品牌名称,以将符号放回原处。然后,当人们使用
&
进行搜索时,如果没有添加额外的
\
,它将是一个精确匹配。这种行为将包含在整个数据中,并且不需要您添加代码来规避FTS的自然操作,这似乎是一种容易出错的方法。

不确定这是否与您的问题有关,但是,&是T-SQL中的位and运算符……以及您的.NET代码。如果您将字符串作为强类型参数传递,则符号and不应在任何地方引起任何问题。无论是否转义,
&
过去是一个特殊字符,您看到的变体可能与它的“转义”无关,但是,在SQL server获取了
&
的含义之后,还可以看到/搜索其他内容。用谷歌搜索它。当你说“在我们的数据库上执行全文搜索”时,你的意思是说你在使用实际的全文搜索功能,还是像“%”++@variable++“%”这样的
操作符?
`不是t-SQL转义,因此如果您不使用全文搜索(其中
&`在使用
包含
函数时也应作为逻辑
),那么您的应用程序代码在没有使用``转义时可能正在翻译
&
。谢谢大家,我已经发布了t-SQL过程的相关部分。恐怕这和按位a有关