我有一个SQL Server表,该表将xml标记存储在varchar字段中,我希望select语句从包含特定值的每一行中返回整个节点。例如:
1. <tag1><tag2 value1 = "abcde" value2 = "fghij"></tag2></tag1>
2. <tag1><tag2 value1 = "hfdgd" value2 = "fgytyhij"></tag2></tag1>
3. <tag1><tag2 value1 = "abcde" value2 = "ettyy"></tag2></tag1>
4. <tag1><tag2 value1 = "qwere" value2 = "mnbvb"></tag2></tag1>
我想搜索术语“ abcde”,并且希望select语句返回:
<tag2 value1 = "abcde" value2 = "fghij">
<tag2 value1 = "abcde" value2 = "ettyy">
我可以使用PATINDEX查找要搜索的图案的位置。我的问题是我无法弄清楚如何找到与搜索字符串最接近的'<'和'>'并返回用'<'和'>'括起来的整个字符串。
答案 0 :(得分:1)
现在应该可以更好地工作了。我在第一篇文章中没有@SearchVal。
declare @TheStrings table(SomeVal varchar(max))
insert @TheStrings values
('<tag1><tag2 value1 = "abcde" value2 = "fghij"></tag2></tag1>')
,('<tag1><tag1a value="asdf"></tag1a><tag2 value11 = "abcde" value3="qwer" value2 = "wow"></tag2></tag1>')
declare @SearchVal varchar(10) = 'abcde'
select
SomeVal
, SUBSTRING(SomeVal, len(SomeVal) - charindex('<', reverse(SomeVal), charindex(reverse(@SearchVal), reverse(SomeVal))) + 1, charindex('>', SUBSTRING(SomeVal, len(SomeVal) - charindex('<', reverse(SomeVal), charindex(reverse(@SearchVal), reverse(SomeVal))) + 1, 100)))
from @TheStrings
答案 1 :(得分:1)
与XML的任何交互都应依靠SQL-Server提供的本机XML方法。在字符串级别(使用诸如CHARINDEX
,SUBSTRING
之类的字符串方法)处理XML是错误的,并且可能会因稍微不同但有效的XML片段而中断。例如,属性的顺序不是文档的一部分。读者会介绍空白和换行符。
例如,您的XML
<tag1><tag2 value1 = "abcde" value2 = "fghij"></tag2></tag1>
可能显示为
<tag1><tag2 value2='fghij' value1='abcde'/></tag1>
从语义上来说,两者都是相同的...字符串方法必须非常通用才能处理此问题...
第一件事是使用本机类型的XML列存储此值。这样可以避免查询中的CAST(... AS XML)
。
DECLARE @mockup TABLE(YourStringXML VARCHAR(MAX))
INSERT INTO @mockup VALUES
('<tag1><tag2 value1 = "abcde" value2 = "fghij"></tag2></tag1>')
,('<tag1><tag2 value1 = "hfdgd" value2 = "fgytyhij"></tag2></tag1>')
,('<tag1><tag2 value1 = "abcde" value2 = "ettyy"></tag2></tag1>')
,('<tag1><tag2 value1 = "qwere" value2 = "mnbvb"></tag2></tag1>');
DECLARE @FindThisInValue1 VARCHAR(10) = 'abcde';
SELECT *
FROM @mockup m
WHERE CAST(YourStringXML AS XML).exist('/tag1/tag2[@value1=sql:variable("@FindThisInValue1")]')=1;
如果在XQuering
下方有<tag2>
,且其属性<tag1>
的值类似于名为{{1}的sql变量,则XML是value1
的XML。 }。
假设本机XML列非常快。提提您:SQL-Server不会将XML存储为您看到的字符串,而是存储为物理结构中的层次结构表。 @FindThisInValue1
和XPath
可以很好地解决这个问题。
答案 2 :(得分:0)
怎么样
DECLARE @Str VARCHAR(400);
SET @Str = '<tag1><tag2 value1 = "abcde" value2 = "fghij"></tag2></tag1>';
SELECT SUBSTRING(@Str, CHARINDEX('>', @Str) +1, CHARINDEX('/', @Str) - 8)
更新:
CREATE TABLE T(
Str VARCHAR(400)
);
INSERT INTO T VALUES
('<tag1><tag2 value1 = "abcde" value2 = "fghij"></tag2></tag1>'),
('<tag1><tag2 value1 = "hfdgd" value2 = "fgytyhij"></tag2></tag1>'),
('<tag1><tag2 value1 = "abcde" value2 = "ettyy"></tag2></tag1>'),
('<tag1><tag2 value1 = "qwere" value2 = "mnbvb"></tag2></tag1>');
SELECT SUBSTRING(Str, CHARINDEX('>', Str) +1, CHARINDEX('/', Str) - 8)
FROM T
WHERE Str LIKE '%"abcde"%';
--or more better
--WHERE Str LIKE '%value1 = "abcde"%';