使用 XML 命名空间声明游标(SQL Server 2012)

Declaring a cursor with XML Namespaces (SQL Server 2012)

我有一个带有默认命名空间 urn:iso:std:iso:20022:tech:xsd:camt.053.001.02 的 XML 文档,我相信我需要使用游标来遍历重复的段。

这是一个非常简化的文件版本:

<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
  <BkToCstmrStmt>
    <GrpHdr>...</GrpHdr>
    <Stmt>
      <Id>1</Id>
      <CreDtTm>2015-06-23T03:25:08.688+01:00</CreDtTm>
    </Stmt>
    <Stmt>
      <Id>2</Id>
      <CreDtTm>2015-06-23T03:25:09.000+01:00</CreDtTm>
    </Stmt>
    <Stmt>
      <Id>3</Id>
      <CreDtTm>2015-06-23T03:25:10.051+01:00</CreDtTm>
    </Stmt>
  </BkToCstmrStmt>
</Document>

我正在根据 SQL 2012 - iterate through an XML list (better alternative to a WHILE loop).

的答案中给出的建议进行构建

如果没有默认值 xmlns,我将能够声明一个游标来遍历 stmt 部分,如下所示:

declare c cursor fast_forward for
select
    s.c.value('(Id/text())[1]', 'integer') as Id,
    s.c.value('(CreDtTm/text())[1]', 'datetime2(3)') as CreDtTm
from @XML_In.nodes('Document/BkToCstmrStmt') as b(c)
    outer apply b.c.nodes('Stmt') as s(c)

这会 return 这个结果集:

Id  CreDtTm
1   2015-06-23 02:25:08.688
2   2015-06-23 02:25:09.000
3   2015-06-23 02:25:10.051

如果我使用普通的 select 语句,我可以像这样声明查询的默认名称空间(给定 @XML_In 是表示 XML 文档的字符串):

with xmlnamespaces(default 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02')
select
    s.c.value('(Id/text())[1]', 'integer') as Id,
    s.c.value('(CreDtTm/text())[1]', 'datetime2(3)') as CreDtTm
from @XML_In.nodes('Document/BkToCstmrStmt') as b(c)
    outer apply b.c.nodes('Stmt') as s(c)

如何将游标的使用与在显式默认名称空间内查询的需要结合起来?

以您链接的问题为例,您是否尝试过将两者简单组合?

DECLARE @XML_in XML = '<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
  <BkToCstmrStmt>
    <GrpHdr>...</GrpHdr>
    <Stmt>
      <Id>1</Id>
      <CreDtTm>2015-06-23T03:25:08.688+01:00</CreDtTm>
    </Stmt>
    <Stmt>
      <Id>2</Id>
      <CreDtTm>2015-06-23T03:25:09.000+01:00</CreDtTm>
    </Stmt>
    <Stmt>
      <Id>3</Id>
      <CreDtTm>2015-06-23T03:25:10.051+01:00</CreDtTm>
    </Stmt>
  </BkToCstmrStmt>
</Document>'


DECLARE cur CURSOR FAST_FORWARD
FOR
with xmlnamespaces(default 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02')
SELECT s.c.value('(Id/text())[1]', 'integer') AS Id
    ,s.c.value('(CreDtTm/text())[1]', 'datetime2(3)') AS CreDtTm
FROM @XML_In.nodes('Document/BkToCstmrStmt') AS b(c)
OUTER APPLY b.c.nodes('Stmt') AS s(c)

declare @Id int
declare @CreDtTm datetime2(3)
OPEN cur

WHILE 1 = 1
BEGIN
    FETCH cur
    INTO @Id
        ,@CreDtTm

    IF @@fetch_status <> 0
        BREAK
    -- Do whatever you like with your cursor
    select @Id, @CreDtTm
END

CLOSE cur

DEALLOCATE cur

结果

----------- ---------------------------
1           2015-06-23 02:25:08.688

(1 row(s) affected)


----------- ---------------------------
2           2015-06-23 02:25:09.000

(1 row(s) affected)


----------- ---------------------------
3           2015-06-23 02:25:10.051

(1 row(s) affected)