我有一个包含下面的XML数据的表列作为为nvarchar(最大):
<?xml version="1.0" encoding="utf-8"?>
<SerializableAlertDetail xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SerializableContextAlertDetail">
<ContextName>Evénements PTI mobile</ContextName>
<EnumValueName>Pré Alerte immobilisme</EnumValueName>
</SerializableAlertDetail>
我想选择“CONTEXTNAME”和“EnumValueName” XML元素的串联。
起初我只是试图返回一个元素,它正常工作:
SELECT CAST(REPLACE(dbo.AlertDetail.Context, 'encoding="utf-8"', '') AS XML).value('(/SerializableAlertDetail/*[local-name() = "ContextName"])[1]', 'nvarchar(max)') As DisplayName FROM Table
因为我不想在查询中投两次,我正在寻找一种方式来解构XML列到一个表,然后从这里选择列。到目前为止,我坚持用下面的查询无效:
SELECT T0.XML.value('ContextName', 'nvarchar(max)')
FROM Table c
CROSS APPLY (SELECT CAST(REPLACE(c.Context, 'encoding="utf-8"', '') AS XML)) as T(X)
CROSS APPLY T.X.nodes('SerializableAlertDetail') AS T0(XML)
但它失败,出现以下错误信息:
的XQuery [T.X.value()]: '值()' 需要单(或空序列),实测值类型的操作数 'XDT:untypedAtomic类型*'
任何帮助表示赞赏。
编辑1
我得出以下查询工作,但可能可能不是最优的:
SELECT T0.XML.query('./ContextName').value('.', 'nvarchar(max)') + T0.XML.query('./EnumValueName').value('.', 'nvarchar(max)')
FROM Table c
CROSS APPLY (SELECT CAST(REPLACE(c.Context, 'encoding="utf-8"', '') AS XML)) as T(X)
CROSS APPLY T.X.nodes('SerializableAlertDetail') AS T0(XML)
编辑2
通过为nvarchar(最大)代替NTEXT;)
你已经被告知,NTEXT
已经废弃了百年;-)
只是一些背景:
NTEXT
是2字节编码的文本和将转化为NVARCHAR
。但是你的XML大喊大叫我是UTF-8 !!!!,这是一个普通的谎言。在NTEXT
它是 - 肯定! - 不是UTF-8。有进行两种方法:
NTEXT
到NVARCHAR
,然后VARCHAR
最后到XML。这将工作,为UTF-8是内滑动拉丁编码1个字节。utf-8
(像你一样),2)utf-16
或3)ucs-2
(正确的事)带走的谎言。关于您的查询:这可以简单一点,因为没有重复的内容,因此没有必要对派生表。尝试这个:
SELECT X.value('(/SerializableAlertDetail/ContextName/text())[1]','nvarchar(max)')
+ X.value('(/SerializableAlertDetail/EnumValueName/text())[1]','nvarchar(max)')
FROM Table c
CROSS APPLY (SELECT CAST(REPLACE(c.Context, 'encoding="utf-8"', '') AS XML)) as T(X);
这应该是快...
在可读性方面,你甚至可以尝试
SELECT X.value('(//ContextName)[1]','nvarchar(max)')
+ X.value('(//EnumValueName)[1]','nvarchar(max)')
FROM Table c
CROSS APPLY (SELECT CAST(REPLACE(c.Context, 'encoding="utf-8"', '') AS XML)) as T(X);