在SQL Server 2012中读取XML数据

问题描述 投票:0回答:3

我想读取xml文件中的xml数据。我有一个包含xml数据的表列。 enter image description here

如果我点击xml文件,它将在Sql server Management studio中打开。 xml文件格式如下所示。

enter image description here

我想只读取NTDomainName,DatabaseName和ServerName,并将该数据写入另一个表中。表格格式如下所示

NTDomainName | DatabaseName | ServerName 
----------
ABC          | TestCube1    | SERXYZ
sql sql-server stored-procedures
3个回答
1
投票

试试这个:

declare @xml xml
set @xml = '<event><data name="NTUserName"><value>MyName</value></data><data name="NTDomainName"><value>DomainName</value></data><data name="ServerName"><value>ServerName</value></data></event>'

select [NTDomainName], [DatabaseName], [ServerName] from
(
    select [name],[value] from (
        select c.value('./@name', 'varchar(100)') [name], c.value('(./value)[1]', 'varchar(100)') [value]
        from @xml.nodes('/event/data') as t(c)
    ) a where [name] in ('NTDomainName', 'DatabaseName', 'ServerName')
) x
pivot (
    max(value) for [name] in ([NTDomainName], [DatabaseName], [ServerName])
) as [pivot_Name] 

最内部的查询将从XML检索信息,每个name属性值需要检索一行。因此,需要转动此查询的输出。


1
投票

我想你是这样的:

SELECT * FROM (
SELECT 
CAST(f.x.query('data(@name)') as varchar(150)) as data_name,
CAST(f.x.query('data(value)') as varchar(150)) as data_value
FROM @xml.nodes('/event') as t(n)
CROSS APPLY t.n.nodes('data') as f(x)) X
PIVOT (MAX(data_value) FOR data_name IN (NTDomainName, DatabaseName, ServerName)) as pvt

0
投票

如果你不想使用PIVOT

DECLARE @DataSource TABLE
(
    [ID] TINYINT IDENTITY(1,1)
   ,[XML] XML
);

INSERT INTO @DataSource ([XML])
VALUES ('<event><data name="SessionID">S1</data><data name="NTUserName">User1</data><data name="DatabaseName">DB1</data><data name="ServerName">SN1</data></event>')
      ,('<event><data name="SessionID">S1</data><data name="NTUserName">User2</data><data name="DatabaseName">DB2</data><data name="ServerName">SN2</data></event>');

SELECT [ID]
      ,MAX(CASE wHEN C.value('(./@name)[1]', 'varchar(50)')  = 'NTUserName' THEN C.value('(.)[1]', 'varchar(50)')  END) AS [NTUserName]
      ,MAX(CASE wHEN C.value('(./@name)[1]', 'varchar(50)')  = 'DatabaseName' THEN C.value('(.)[1]', 'varchar(50)')  END) AS [DatabaseName]
      ,MAX(CASE wHEN C.value('(./@name)[1]', 'varchar(50)')  = 'ServerName' THEN C.value('(.)[1]', 'varchar(50)')  END) AS [ServerName]
FROM @DataSource
CROSS APPLY [XML].nodes('event/data[@name = "NTUserName" or @name = "DatabaseName" or @name = "ServerName"]') T(c)
GROUP BY [ID];

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.