在我的一个表列(nvarchar)中,数据以XML格式存储。
在此示例中,数据如下所示:
<Datatype id="76" name="Disp_Dest" hdl="47/4/SB8_3-910-8243-19/0/76" odobjid="385">
<Datatypevalue id="1" name="LowPressureRinse" />
<Datatypevalue id="0" name="ShortInlet" />
</Datatype>
我查了几个SQL Server函数,我需要定义命名空间才能提取出来的值。
正确格式化,以便我可以知道要检索的字段。
<Datatype id="76" name="Disp_Dest" hdl="47/4/SB8_3-910-8243-19/0/76" odobjid="385">
<Datatypevalue id="1" name="LowPressureRinse" />
<Datatypevalue id="0" name="ShortInlet" />
</Datatype>
预期输出为
Disp_Dest, LowPressureRinse
Disp_Dest, ShortInlet
您认为使用SQL Server XML相关功能可以实现这一目标吗?
感谢。
答案 0 :(得分:1)
以下是使用Value
和Query
方法
DECLARE @xml XML = '<Datatype id="76" name="Disp_Dest" hdl="47/4/SB8_3-910-8243-19/0/76" odobjid="385">
<Datatypevalue id="1" name="LowPressureRinse" />
<Datatypevalue id="0" name="ShortInlet" />
</Datatype>'
SELECT CONVERT(VARCHAR(1000), @xml.query('data(Datatype/@name[1])')),
c.value('@name', 'varchar(1000)')
FROM @xml.nodes('Datatype/Datatypevalue') x (c)
答案 1 :(得分:0)
您不应将XML存储为字符串。如果你可以改变它,你应该真正使用本机类型的XML列!
原因:XML不是存储为您看到的字符串,而是存储为层次结构树。处理此树不需要字符串解析。但在您的情况下,您将不得不在每次调用中重新创建此层次结构树。这非常贵!
试试这样:
DECLARE @mockup TABLE(ID INT IDENTITY,YourStringXML XML);
INSERT INTO @mockup VALUES
(N'<Datatype id="76" name="Disp_Dest" hdl="47/4/SB8_3-910-8243-19/0/76" odobjid="385">
<Datatypevalue id="1" name="LowPressureRinse" />
<Datatypevalue id="0" name="ShortInlet" />
</Datatype>')
,(N'<Datatype id="11" name="SomeOther" hdl="blah" odobjid="111">
<Datatypevalue id="1" name="blubb" />
<Datatypevalue id="0" name="foo" />
</Datatype>');
SELECT m.ID
,A.Casted.value(N'/Datatype[1]/@id',N'int') AS dt_Id
,A.Casted.value(N'/Datatype[1]/@name',N'nvarchar(max)') AS dt_name
,A.Casted.value(N'/Datatype[1]/@hdl',N'nvarchar(max)') AS dt_hdl
,A.Casted.value(N'/Datatype[1]/@odobjid',N'nvarchar(max)') AS dt_odobjid
,dtv.value(N'@id',N'int') AS dtv_Id
,dtv.value(N'@name',N'nvarchar(max)') AS dtv_name
FROM @mockup AS m
OUTER APPLY (SELECT CAST(m.YourStringXML AS XML)) AS A(Casted)
OUTER APPLY A.Casted.nodes(N'/Datatype/Datatypevalue') AS B(dtv);
只需将@mockup
更改为您实际的表名称并调整列名称。
第一个APPLY
将输入XML,第二个APPLY
使用.nodes()
获取内部<Datatypevalue>
元素。
结果
+----+-------+-----------+-----------------------------+------------+--------+------------------+
| ID | dt_Id | dt_name | dt_hdl | dt_odobjid | dtv_Id | dtv_name |
+----+-------+-----------+-----------------------------+------------+--------+------------------+
| 1 | 76 | Disp_Dest | 47/4/SB8_3-910-8243-19/0/76 | 385 | 1 | LowPressureRinse |
+----+-------+-----------+-----------------------------+------------+--------+------------------+
| 1 | 76 | Disp_Dest | 47/4/SB8_3-910-8243-19/0/76 | 385 | 0 | ShortInlet |
+----+-------+-----------+-----------------------------+------------+--------+------------------+
| 2 | 11 | SomeOther | blah | 111 | 1 | blubb |
+----+-------+-----------+-----------------------------+------------+--------+------------------+
| 2 | 11 | SomeOther | blah | 111 | 0 | foo |
+----+-------+-----------+-----------------------------+------------+--------+------------------+