在SQL Server 2012中,我有一个表DEFINITIONS
和其中的一列,该列的值为XML,列的名称为“ XML”。我想从XML列(在参数标签中)提取字符串“ [CDATA [xxxx]]”。我该怎么办?
XML示例值:
<CatalogItem subType="0" type="82">
<id>7c75be9f-d490-4ff5-81ed-064349f4efde</id>
<name>Test White</name>
<description />
<attributes>0</attributes>
<parameters><conditions><condition grouping="or"><prop-key>usb_device_serial_number</prop-key><op-key>equals</op-key><value><![CDATA[gdefgd||]]></value></condition></conditions></parameters>
<customParameterNames />
<enforceProducts>
<Product type="WIN" />
</enforceProducts>
</CatalogItem>
更新1
此查询解决了我的问题:
if object_id('dbo.cdata') is not null drop table dbo.cdata;
create table dbo.cdata(
x xml
);
insert into dbo.cdata(x)
SELECT XML FROM [HQ-MC-SRV-01].[dbo].[DEFINITIONS]
select
xv.v.value('.', 'nvarchar(max)') as cdata
from dbo.cdata
cross apply
cdata.x.nodes(
'//parameters'
) as pp(p)
cross apply (
values(
cast(pp.p.value(
'.', 'nvarchar(max)'
) as xml)
)
) as xp(p)
cross apply
xp.p.nodes('//value') as xv(v)
;
非常感谢Andrei Odegov
更新2
我也必须使用先前的查询从该XML中提取“ serialNumber”和“ endUser”。
<CatalogItem subType="0" type="93">
<id>9d6825e6-fa89-44e1-8e0f-61768016624c</id>
<name>tteesstt</name>
<description />
<attributes>0</attributes>
<entries>
<entry>
<serialNumber>zsxxdx</serialNumber>
<userType>user</userType>
<endUser>farhad@drf.local</endUser>
<description />
</entry>
</entries>
</CatalogItem>
更新3
<CatalogItem subType="0" type="12">
<id>169d6139-bdb6-4fff-88e6-09f00dd2f155</id>
<name>za</name>
<description />
<attributes>0</attributes>
<SIDMode>true</SIDMode>
<nameIdentificationType>1</nameIdentificationType>
<entries>
<entry>
<name>farhad</name>
<path>CN=farhad,CN=Users,DC=DCVLAB,DC=LOCAL</path>
<uid>F7A84834EAC8984AA7FBEAD7A5539432</uid>
<serverName>192.168.7.2</serverName>
<sid>S-1-5-21-907365782-933549064-1582919620-1103</sid>
<type>user</type>
</entry>
</entries>
</CatalogItem>
答案 0 :(得分:3)
考虑到您的测试数据,您可以尝试修改以下代码:
declare @x xml = '
<CatalogItem subType="0" type="82">
<id>7c75be9f-d490-4ff5-81ed-064349f4efde</id>
<name>Test White</name>
<description />
<attributes>0</attributes>
<parameters><conditions><condition grouping="or"><prop-key>usb_device_serial_number</prop-key><op-key>equals</op-key><value><![CDATA[gdefgd||]]></value></condition></conditions></parameters>
<customParameterNames />
<enforceProducts>
<Product type="WIN" />
</enforceProducts>
</CatalogItem>
';
select cast(@x.value('(//parameters)[1]', 'nvarchar(max)') as xml).query('//value/text()') as cdata;
+----------+
| cdata |
+----------+
| gdefgd|| |
+----------+
if object_id('dbo.cdata') is not null drop table dbo.cdata;
create table dbo.cdata(
x xml
);
insert into dbo.cdata(x)
values ('
<CatalogItem subType="0" type="82">
<id>7c75be9f-d490-4ff5-81ed-064349f4efde</id>
<name>Test White</name>
<description />
<attributes>0</attributes>
<parameters><conditions><condition grouping="or"><prop-key>usb_device_serial_number</prop-key><op-key>equals</op-key><value><![CDATA[gdefgd||]]></value><value><![CDATA[foo]]></value></condition></conditions></parameters>
<parameters><conditions><condition grouping="or"><prop-key>usb_device_serial_number</prop-key><op-key>equals</op-key><value><![CDATA[gdefgd||170]]></value><value><![CDATA[foo170]]></value></condition></conditions></parameters>
<customParameterNames />
<enforceProducts>
<Product type="WIN" />
</enforceProducts>
</CatalogItem>
'), ('
<CatalogItem subType="0" type="82">
<id>7c75be9f-d490-4ff5-81ed-064349f4efde</id>
<name>Test White</name>
<description />
<attributes>0</attributes>
<parameters><conditions><condition grouping="or"><prop-key>usb_device_serial_number</prop-key><op-key>equals</op-key><value><![CDATA[gdefgd||42]]></value><value><![CDATA[foo42]]></value></condition></conditions></parameters>
<customParameterNames />
<enforceProducts>
<Product type="WIN" />
</enforceProducts>
</CatalogItem>
');
select
xv.v.value('.', 'nvarchar(max)') as cdata
from dbo.cdata
cross apply
cdata.x.nodes(
'//parameters'
) as pp(p)
cross apply (
values(
cast(pp.p.value(
'.', 'nvarchar(max)'
) as xml)
)
) as xp(p)
cross apply
xp.p.nodes('//value') as xv(v);
您可以在“ XQuery Language Reference (SQL Server)”中获得有关使用XML数据在Sql Server中工作的更多详细信息。
在CROSS
和OUTER
{{ 3}}运算符及其在XML数据中的应用示例。
select
replace(xv.v.value('.', 'nvarchar(max)'), '|', '') as cdata,
xci.ci.value('(//serialNumber)[1]', 'nvarchar(15)') as sn,
xci.ci.value('(entries/entry/endUser)[1]', 'nvarchar(50)') as eu,
xci.ci.value('(entries/entry/name)[1]', 'nvarchar(50)') as name
from dbo.cdata
cross apply
cdata.x.nodes('/CatalogItem') as xci(ci)
outer apply
xci.ci.nodes('parameters') as pp(p)
outer apply (
values(
cast(pp.p.value(
'.', 'nvarchar(max)'
) as xml)
)
) as xp(p)
outer apply
xp.p.nodes('//value') as xv(v);
+-----------+--------+------------------+--------+
| cdata | sn | eu | name |
+-----------+--------+------------------+--------+
| gdefgd | zsxxdx | farhad@drf.local | NULL |
| foo | zsxxdx | farhad@drf.local | NULL |
| gdefgd170 | zsxxdx | farhad@drf.local | NULL |
| foo170 | zsxxdx | farhad@drf.local | NULL |
| NULL | foobar | user@mail.net | NULL |
| NULL | NULL | NULL | farhad |
+-----------+--------+------------------+--------+
使用APPLY
在线进行测试。