在SQL Server XML数据类型上使用LIKE语句


86

如果您有varchar字段,则可以轻松SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%'查看该列是否包含某个字符串。

您如何针对XML类型执行此操作?

我有以下内容,仅返回具有“文本”节点的行,但我需要在该节点内搜索

select * from WebPageContent where data.exist('/PageContent/Text') = 1

Answers:


70

您应该能够很容易地做到这一点:

SELECT * 
FROM WebPageContent 
WHERE data.value('(/PageContent/Text)[1]', 'varchar(100)') LIKE 'XYZ%'

.value方法为您提供了实际值,您可以定义该值作为VARCHAR()返回,然后可以使用LIKE语句进行检查。

请注意,这不会太快。因此,如果您的XML中有某些字段需要大量检查,则可以:

  • 创建一个存储函数,该函数获取XML并以VARCHAR()的形式返回您要查找的值
  • 在您的表上定义一个新的计算字段,该字段将调用此函数,并将其设为PERSISTED列

这样,您基本上可以将XML的特定部分“提取”到一个计算字段中,使其持久化,然后就可以非常高效地对其进行搜索(哎呀,您甚至可以索引该字段!)。

马克


1
我基本上是在实现搜索功能,所以我只想在“文本”节点上搜索XML列,然后返回一个子字符串以指示搜索已找到匹配项。例如,在“ hi there”上搜索而不是返回整个xml列,我只返回一个子字符串,例如“ chap说嗨并携带...”
Jon

1
击败我5秒钟。如果您的数据可以接受,则另一种可能性是考虑使用自由文本搜索
RickNZ

10
搜索整个文件:WHERE xmlField.value('。','varchar(max)')LIKE'%FOO%'
jhilden

如果返回NULL,请注意讨厌的Xml名称空间
Simon_Weaver

86

另一个选择是将XML强制转换为nvarchar,然后搜索给定的字符串,就像XML使用了nvarchar字段一样。

SELECT * 
FROM Table
WHERE CAST(Column as nvarchar(max)) LIKE '%TEST%'

我喜欢这种解决方案,因为它干净,易于记忆,难以弄乱,并且可以用作where子句的一部分。

编辑:正如悬崖提到的那样,您可以使用:

... nvarchar(如果某些字符不能转换为varchar)


3
同上,或nvarchar(如果有未转换为varchar的字符)SELECT * FROM Table WHERE CAST(列为nvarchar(max))LIKE'%TEST%'
Cliff Coulter

[Err] 42000-[SQL Server]无法将一个或多个字符从XML转换为目标排序规则
digz6666

[Err] 22018-[SQL Server]不允许从数据类型xml到文本的明确转换。
digz6666

听起来您在做错事@ digz6666
Squazz

1
@Squazz您昨天对这个答案进行了最后投票。除非已编辑此答案,否则您的投票现已锁定。:)
digz6666 '17

10

另一种选择是通过将XML转换为字符串然后使用LIKE来搜索XML作为字符串。但是,由于计算列不能成为WHERE子句的一部分,因此需要将其包装在另一个SELECT中,如下所示:

SELECT * FROM
    (SELECT *, CONVERT(varchar(MAX), [COLUMNA]) as [XMLDataString] FROM TABLE) x
WHERE [XMLDataString] like '%Test%'

请注意,这可能会绕过您可能拥有的所有选择性xml索引,从而影响性能。
Rudy Hinojosa

0

这是我将基于marc_s答案使用的:

SELECT 
SUBSTRING(DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)'),PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')) - 20,999)

FROM WEBPAGECONTENT 
WHERE COALESCE(PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')),0) > 0

在存在搜索条件的搜索中返回子字符串


我是否需要参数来防止注入?
乔恩

2
注意:那些XML函数区分大小写-DATA.VALUE不起作用!它必须是.value(...)
marc_s
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.