2012-01-10 29 views
3

以下是我正在做的事情。我将XML文件插入XML列,与其他栏目如日期戳记等进行记录沿(这些都是无关紧要的这一请求)使用SQL Server将XML文件分解为单独的行

的文件看起来像类似于这样:

<topLevelItem> 
    <secondLevelItem> 
    <secondLevelItemDetail> 
    </secondLevelItemDetail> 
    <secondLevelItemAnotherDetail> 
    </secondLevelItemAnotherDetail> 
    </secondLevelItem> 
    <secondLevelItem> 
    <secondLevelItemDetail> 
    </secondLevelItemDetail> 
    <secondLevelItemAnotherDetail> 
    </secondLevelItemAnotherDetail> 
    </secondLevelItem> 
    <secondLevelItem> 
    <secondLevelItemDetail> 
    </secondLevelItemDetail> 
    <secondLevelItemAnotherDetail> 
    </secondLevelItemAnotherDetail> 
    </secondLevelItem> 
<topLevelItem> 

我的目标是能够查询XML字段并获取每个<secondLevelItem>在它自己的行中的结果集,以XML格式显示。如下面:

行1:

<secondLevelItem> 
    <secondLevelItemDetail> 
    </secondLevelItemDetail> 
    <secondLevelItemAnotherDetail> 
    </secondLevelItemAnotherDetail> 
    </secondLevelItem> 

行2:

<secondLevelItem> 
    <secondLevelItemDetail> 
    </secondLevelItemDetail> 
    <secondLevelItemAnotherDetail> 
    </secondLevelItemAnotherDetail> 
    </secondLevelItem> 

行3:

<secondLevelItem> 
    <secondLevelItemDetail> 
    </secondLevelItemDetail> 
    <secondLevelItemAnotherDetail> 
    </secondLevelItemAnotherDetail> 
    </secondLevelItem> 

这给使用Microsoft SQL Server来完成,而无需使用CLI。我需要能够声明哪个XML节点是我想要分解的,因为有些文件具有我不需要的其他XML元素。所以像WHERE node = secondLevelItem

回答

2

使用SQL Server 2005及更新版本,SQL Server中有出色的XQuery支持。

这种方法在这里将要使用的.nodes().query()方法:

SELECT 
    Col.query('.') 
FROM 
dbo.YourTable 
CROSS APPLY 
    YourXmlColumn.nodes('/topLevelItem/secondLevelItem') AS Tbl(Col) 
WHERE 
    (some condition) 

.nodes()函数创建一个“暂时的,内联”伪代码表Tbl与单个列Col其包含用于在每个节点一个XML条目您的XML列与匹配的XPath匹配(在这种情况下:<topLevelItem>中的每个<secondLevelItem>都将匹配)。

由于您希望为每个XML元素使用整个XML,只需使用.query('.')即可返回完整的XML元素。

1

使用nodes()来碎化您的XML并使用local-name()sql:variable()找到您想要的节点,然后使用query()检索XML。

declare @NodeName varchar(100) = 'secondLevelItem' 

select T.N.query('.') 
from YourTable 
    cross apply XMLCol.nodes('//*[local-name()=sql:variable("@NodeName")]') as T(N) 
1

如果您只是将原始XML提供给存储过程而不从表中提取,则可以执行以下操作。

DECLARE @XML xml 
SET @XML = '<topLevelItem> 
    <secondLevelItem> 
    <secondLevelItemDetail>One</secondLevelItemDetail> 
    <secondLevelItemAnotherDetail>One One</secondLevelItemAnotherDetail> 
    </secondLevelItem> 
    <secondLevelItem> 
    <secondLevelItemDetail>Two</secondLevelItemDetail> 
    <secondLevelItemAnotherDetail>Two Two</secondLevelItemAnotherDetail> 
    </secondLevelItem> 
    <secondLevelItem> 
    <secondLevelItemDetail>Three</secondLevelItemDetail> 
    <secondLevelItemAnotherDetail>Three Three</secondLevelItemAnotherDetail> 
    </secondLevelItem> 
</topLevelItem>' 


SELECT 
    Tbl.Col.query('.') 
FROM 
    @XML.nodes('/topLevelItem/secondLevelItem') AS Tbl(Col)