如何在SQL Server 2008中循环访问某些XML数据?

时间:2015-06-16 22:54:47

标签: xml sql-server-2008

我已经挣扎了2.5个小时,并且可以真正使用一些帮助。可以包含任意数量的附件,我试图从每个附件中提取FILENAME和DESCRIPTION。这是我的代码(请原谅我们)我将非常感谢您提供的任何帮助。谢谢!

DECLARE
   @myXML XML = NULL
  ,@hDoc  INT = 0
  ,@Num   VARCHAR(2)
  ,@Type  VARCHAR(5)
  ,@FileName    VARCHAR(32) = ''
  ,@Description VARCHAR(256) = '';

SET @myXML = '
<REPORT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" DESCRIPTION="TestOrder" FILENUM="1234">
    <ADDENDA>
        <ATTACHMENTS>
            <ATTACHMENT NUM="1" TYPE="1">
                <FILENAME>4215.pdf</FILENAME>
                <DESCRIPTION>Sales Contract</DESCRIPTION>
                <CONTENT>...</CONTENT>
            </ATTACHMENT>
            <ATTACHMENT NUM="2" TYPE="1">
                <FILENAME>6719.pdf</FILENAME>
                <DESCRIPTION>Contract Instruction</DESCRIPTION>
                <CONTENT>...</CONTENT>
            </ATTACHMENT>
        </ATTACHMENTS>
    </ADDENDA>
</REPORT>';

----------------------------------------------------------------------------
EXEC sp_xml_preparedocument @hDoc OUTPUT, @myXML;
----------------------------------------------------------------------------
-- Begin get required docs 
DECLARE xDocsCursor CURSOR FOR
  SELECT    *
  FROM OPENXML (@hDoc, '/REPORT/ADDENDA/ATTACHMENTS/ATTACHMENT',1)
          WITH ([NUM]  varchar(32),
                [TYPE] varchar(5))
          WHERE [NUM] IS NOT NULL;
OPEN xDocsCursor;

FETCH NEXT FROM xDocsCursor INTO @Num, @Type;
WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT @Num, @Type;
  -------------------
  FETCH NEXT FROM xDocsCursor INTO @Num, @Type;
END
CLOSE xDocsCursor;
DEALLOCATE xDocsCursor;
-- End get required docs /REPORT/TRACKING/REQUIREDDATA
----------------------------------------------------------------------------
----------------------------------------------------------------------------
EXEC sp_xml_removedocument @hDoc;
----------------------------------------------------------------------------

2 个答案:

答案 0 :(得分:1)

我会使用SQL Server中的原生XQuery 支持来做到这一点 - 比简单OpenXML方法更简单,更简洁:

SELECT
    Num = XAttachments.value('@NUM', 'int'),
    [Type] = XAttachments.value('@TYPE', 'int'),
    FileName = XAttachments.value('(FILENAME)[1]', 'varchar(100)'),
    Description = XAttachments.value('(DESCRIPTION)[1]', 'varchar(100)')
FROM 
    @myxml.nodes('/REPORT/ADDENDA/ATTACHMENTS/ATTACHMENT') AS XT(XAttachments)

产生输出:

enter image description here

答案 1 :(得分:0)

您只需将其添加到OPENXML

即可
SELECT    *
FROM OPENXML (@hDoc, '/REPORT/ADDENDA/ATTACHMENTS/ATTACHMENT',1)
      WITH ([NUM]  varchar(32),
            [TYPE] varchar(5),              
            [FILENAME] VARCHAR(25) './FILENAME',
            DESCRIPTION VARCHAR(50) './DESCRIPTION',
            CONTENT VARCHAR(50) './CONTENT')
      WHERE [NUM] IS NOT NULL;

我不太确定你为什么要在这里使用CURSOR,因为你可以在单个表中以这种方式返回行以进行操作/查询。如果你更喜欢现代的&#39; XQuery格式,在这里(这不需要运行sp_xml_preparedocument,并且应该表现更好)。

SELECT x.value('@NUM', 'VARCHAR(32)') as NUM
      ,x.value('@TYPE', 'VARCHAR(5)') as TYPE
      ,x.value('./FILENAME[1]', 'VARCHAR(30)') AS FILENAME
      ,x.value('./DESCRIPTION[1]', 'VARCHAR(30)') AS DESCRIPTION
      ,x.value('./CONTENT[1]', 'VARCHAR(30)') AS CONTENT
FROM @myXML.nodes('/REPORT/ADDENDA/ATTACHMENTS/ATTACHMENT') T(x)