使用SQLServer2008R2
我目前有XML标签,其中包含XML标签内的数据(不在它们之间),例如:
<zooid="1"><animals key="all" zebras="22" dogs="0" birds="4" /><animals key="all" workers="yes" vacation="occasion" /> ... *(more)*</zooid>
<zooid="2"><animals key="house" zebras="0" dogs="1" birds="2" /><animals key="house" workers="no" vacation="no" /> ... *(more)*</zoodid>
如果我查询XML或对其使用值函数,它将返回空值,因为它尝试在标记之间读取 - 其中不存在值。我需要它来读取内部标签,将等号前的值解析为列,将引号之间的值解析为这些列中的值(授予,我可以创建一个可以执行此操作的函数,但这会非常细致,我很好奇这样的事情是否已经存在)。在列:
中应该是什么样子Key | Zebras | Dogs | Birds | Key | Workers | Vacation | ... *(more)*
...这是数据行:
all | 22 | 0 | 4 | all | yes | occasion | ... *(more)*
house | 0 | 1 | 2 | house | no | no | ... *(more)*
所以最后的输出(从现在开始只使用两个XML行),看起来就像表格中的以下数据一样:
Key | Zebras | Dogs | Birds | Key | Workers | Vacation | ... *(more)*
================================================================
all | 22 | 0 | 4 | all | yes | occasion | ... *(more)*
house | 0 | 1 | 2 | house | no | no | ... *(more)*
除了查询XML,使用.query
工具甚至尝试.node
工具(使用CROSS APPLY
请参阅this thread),我还无法生成此
答案 0 :(得分:1)
您的xml似乎无效。你怎么能指定这样的元素:?通常xml结构是&lt;(elementName)(Attribute)=&#34;(Value)&#34; /&gt;。除非我错误地将你的文本转换为xml,否则它将失败。假设我可以在自动提取示例中显示正确xml的工作示例,该示例将在SQL Managment Studio中按原样运行。
declare @text1 varchar(max) = '<zooid="1"><animals="all" zebras="22" dogs="0" birds="4" /><animals="all" workers="yes" vacation="occasion" /></zooid>'
, @text2 varchar(max) = '<a zooid="1"><b animals="all" zebras="22" dogs="0" birds="4" /><b animals="all" workers="yes" vacation="occasion" /></a>'
, @xml xml
;
begin try
set @xml = cast(@text1 as xml)
end try
begin catch
set @xml = '<ElementName Attribute="BadData Elements are not named" />'
end catch
select @xml
begin try
set @xml = cast(@text2 as xml)
end try
begin catch
set @xml = '<ElementName Attribute="BadData" />'
end catch
select
@xml.value('(/a/b/@animals)[1]', 'varchar(20)') as AnimalsValue
, @xml.value('(/a/b/@zebras)[1]', 'int') as ZebrasValue
, @xml.value('(/a/b/@dogs)[1]', 'int') as DogsValue
, @xml.value('(/a/b/@birds)[1]', 'int') as BirdsValue
, @xml.value('(/a/b/@workers)[1]', 'varchar(16)') as Workers
, @xml.value('(/a/b/@vacation)[1]', 'varchar(16)') as Vacation
&#39; .value&#39; method是在SQL中查询xml的语法。我基本上找到了元素(我做了包含b的泛型)。然后,一旦达到我想要的水平&#39; @ animals&#39;代表名称动物的属性&#39;。 [1]是一个位置,因为我一次只能返回一个东西,所以我选择了第一个位置。然后需要返回一个数据类型。文本是varchar,数字是整数。
XML查询方法:http://msdn.microsoft.com/en-us/library/ms190798.aspx
答案 1 :(得分:1)
试试这个 -
DECLARE @YourXML NVARCHAR(MAX)
SELECT @YourXML = '
<zooid="1">
<animals key="all" zebras="22" dogs="0" birds="4" />
<animals key="all" workers="yes" vacation="occasion" />
</zooid>
<zooid="2">
<animals key="house" zebras="0" dogs="1" birds="2" />
<animals key="house" workers="no" vacation="no" />
</zoodid>'
DECLARE @XML XML
SELECT @XML =
REPLACE(
REPLACE(@YourXML, 'zooid=', 'zooid id=')
, '</zoodid>'
, '</zooid>')
SELECT
d.[Key]
, Dogs = MAX(d.Dogs)
, Zebras = MAX(d.Zebras)
, Birds = MAX(d.Birds)
, Workers = MAX(d.Workers)
, Vacation = MAX(d.Vacation)
FROM (
SELECT
[Key] = t.p.value('./@key', 'NVARCHAR(50)')
, Zebras = t.p.value('./@zebras', 'INT')
, Dogs = t.p.value('./@dogs', 'INT')
, Birds = t.p.value('./@birds', 'INT')
, Workers = t.p.value('./@workers', 'NVARCHAR(20)')
, Vacation = t.p.value('./@vacation', 'NVARCHAR(20)')
FROM @XML.nodes('/zooid/animals') t(p)
) d
GROUP BY d.[Key]