我有以下在我的数据库中复制的XML文件
<ns2:procedure1 xmlns:ns2="http://www.endpoint.com/">
<auth>
<company>TEST Company</company>
<lineOfBusiness>Sales</lineOfBusiness>
<caseNumber>00001</caseNumber>
<creationDate>2013-12-04</creationDate>
<reviews>
<reviews>
<reviewNumber>ZA1010</reviewNumber>
<revision>1</revision>
<sequence>1</sequence>
</reviews>
<reviews>
<reviewNumber>ZA1010</reviewNumber>
<revision>2</revision>
<sequence>2</sequence>
</reviews>
<reviews>
<reviewNumber>ZA1010</reviewNumber>
<revision>3</revision>
<sequence>3</sequence>
</reviews>
</reviews>
</auth>
</ns2:procedure1 xmlns:ns2="http://www.endpoint.com/">
我使用以下代码:
DECLARE @XML AS XML
DECLARE @hDoc AS INT
DECLARE @SQL NVARCHAR (MAX)
SELECT @XML = XMLData
FROM MYDatabase
DECLARE @rootxmlns VARCHAR(200)
SET @rootxmlns = '<root xmlns:ns2="http://www.endpoint.com/"/>'
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML, @rootxmlns
SELECT *
FROM OPENXML(@hDoc, N'/ns2:procedure1/auth')
WITH (company NVARCHAR(25) 'company',
lineOfBusiness NVARCHAR(50) 'lineOfBusiness',
caseNumber NVARCHAR(30) 'caseNumber',
creationDate DATETIME2 'creationDate',
reviews_reviews_reviewNumber NVARCHAR(20)'reviews/reviews/reviewNumber',
reviews_reviews_revision INT 'reviews/reviews/revision',
reviews_reviews_sequence INT 'reviews/reviews/sequence')
EXEC sp_xml_removedocument @hDoc
此查询仅检索第一个评论信息,但我需要检索所有评论信息。我不知道每个块有多少评论。也许一个街区只有一个评论,但其他街区可以有10个评论。我不知道如何创建一个灵活的查询来做到这一点。我感谢任何帮助。
答案 0 :(得分:1)
我发现使用sqlxml
对于查询xml非常方便,在您的情况下,您需要nodes()
和value()
函数:
;with xmlnamespaces ('http://www.endpoint.com/' as ns2)
select
T.C.value('(../../company/text())[1]', 'nvarchar(max)') as Company,
T.C.value('(../../lineOfBusiness/text())[1]', 'nvarchar(max)') as lineOfBusiness,
T.C.value('(../../caseNumber/text())[1]', 'nvarchar(max)') as caseNumber,
T.C.value('(../../creationDate/text())[1]', 'datetime2') as creationDate,
T.C.value('(reviewNumber/text())[1]', 'nvarchar(max)') as reviewNumber,
T.C.value('(revision/text())[1]', 'nvarchar(max)') as revision,
T.C.value('(sequence/text())[1]', 'nvarchar(max)') as sequence
from @Data.nodes('ns2:procedure1/auth/reviews/reviews') as T(C)
也可以使用嵌套的nodes()
函数:
;with xmlnamespaces ('http://www.endpoint.com/' as ns2)
select
A.C.value('(company/text())[1]', 'nvarchar(max)') as Company,
A.C.value('(lineOfBusiness/text())[1]', 'nvarchar(max)') as lineOfBusiness,
A.C.value('(caseNumber/text())[1]', 'nvarchar(max)') as caseNumber,
A.C.value('(creationDate/text())[1]', 'datetime2') as creationDate,
R.C.value('(reviewNumber/text())[1]', 'nvarchar(max)') as reviewNumber,
R.C.value('(revision/text())[1]', 'nvarchar(max)') as revision,
R.C.value('(sequence/text())[1]', 'nvarchar(max)') as sequence
from @Data.nodes('ns2:procedure1/auth') as A(C)
outer apply A.C.nodes('reviews/reviews') as R(C)
但无论如何,要获得所有评论,您必须将ns2:procedure1/auth/reviews/reviews
xpath路径转换为openxml
(或nodes()
)函数,这样您就可以将所有评论都记录为行。< / p>
如果您真的想使用openxml
,请更改您的查询,如:
...
SELECT *
FROM OPENXML(@hDoc, N'/ns2:procedure1/auth/reviews/reviews')
WITH (company NVARCHAR(25) '../../company',
lineOfBusiness NVARCHAR(50) '../../lineOfBusiness',
caseNumber NVARCHAR(30) '../../caseNumber',
creationDate DATETIME2 '../../creationDate',
reviews_reviews_reviewNumber NVARCHAR(20)'reviewNumber',
reviews_reviews_revision INT 'revision',
reviews_reviews_sequence INT 'sequence')
...
<强> sql fiddle demo 强>