【问题标题】:Unable to Query XML file with OPENXML in SQL无法在 SQL 中使用 OPENXML 查询 XML 文件
【发布时间】:2017-01-06 17:13:05
【问题描述】:

我正在尝试使用 SQL Server 2014 查询大量 XML 文件。我正在使用以下代码,但我不确定语法有什么问题,因为没有返回任何内容。我怀疑 XML 文件有些奇怪。

如果只将部分 XML 文本直接放入查询文件而不是在本地指向它,那么它似乎可以工作,但我有很多文件,并且确实需要能够从本地源查询而无需手动操作的文件。

示例 XML:https://s3.amazonaws.com/irs-form-990/201600349349300510_public.xml

我的代码:

DECLARE @x xml
SELECT @x = R
FROM OPENROWSET (BULK 'C:\Users\USER\990\Example.xml', SINGLE_BLOB) AS     ReturnData(R)

SELECT @x

DECLARE @hdoc int

EXEC sp_xml_preparedocument @hdoc OUTPUT, @x

SELECT * FROM OPENXML (@hdoc, '/Return/ReturnData/IRS990ScheduleHIRS990ScheduleH/FinancialAssistanceAtCostTyp',3)  
  WITH (FinancialAssistancePolicyInd  int   '../FinancialAssistancePolicyInd',  
        FPGReferenceDiscountedCareInd int   '../FPGReferenceDiscountedCareInd',
        PersonsServedCnt int,
        NetCommunityBenefitExpnsAmt int)  

EXEC sp_xml_removedocument @hdoc

提前致谢。如果有更好的方法可以做到这一点,请告诉我,我是在 SQL 中使用 XML 的新手。

【问题讨论】:

    标签: mysql sql sql-server xml openxml


    【解决方案1】:

    有几个缺陷:

    • FROM OPENXML 已过时,不应再使用(存在极少数例外)

    • 您的 XML 包含一个必须声明的默认命名空间

    • 您的 XPath 错误:/Return/ReturnData/IRS990ScheduleHIRS990ScheduleH/ 应该是 /Return/ReturnData/IRS990ScheduleH/

    但无论如何你应该转向现代XQuerymethods。试试这样:

    --这会将 XML 读入声明的变量中。

    --注意您的 XML 声明为 utf-8,这可能会导致特殊字符出现问题...

    DECLARE @x xml
    SELECT @x = R
    FROM OPENROWSET (BULK 'C:\Users\USER\990\Example.xml', SINGLE_BLOB) AS ReturnData(R);
    

    --这是查询,首先声明命名空间,然后使用.nodes().value()

    WITH XMLNAMESPACES(DEFAULT 'http://www.irs.gov/efile'
                              ,'http://www.w3.org/2001/XMLSchema-instance' AS xsi)
    SELECT ct.value('(FinancialAssistancePolicyInd)[1]','int') AS FinancialAssistancePolicyInd
          ,ct.value('(FPGReferenceDiscountedCareInd)[1]','int') AS FPGReferenceDiscountedCareInd
          ,ct.value('(FinancialAssistanceAtCostTyp/PersonsServedCnt)[1]','int') AS PersonsServedCnt
          ,ct.value('(FinancialAssistanceAtCostTyp/NetCommunityBenefitExpnsAmt)[1]','int') AS NetCommunityBenefitExpnsAmt
    FROM @x.nodes('/Return/ReturnData/IRS990ScheduleH') AS A(ct)
    

    【讨论】:

    • 非常感谢您的理论和查询!真的很欣赏它。我认为您是对的,特殊字符将成为问题,您发送的代码不适用于 XML 文档的该部分,而是适用于看起来更干净的早期部分。 (让我知道代码是否应该正常工作,我可能犯了一个错误。)你对我如何处理特殊字符有什么建议吗?
    • @riyadude 关于特殊字符:我建议将字符串读入NVARCHAR(MAX) 类型的变量,然后删除<?xml ...?> 声明并将其设置为XML 类型的变量。特殊字符需要为NVARCHAR(2 字节unicode),如果您不想将问号作为占位符......这不起作用(cannot-switch-encoding-error)。关于让我知道代码是否应该正常工作:这个我不知道......
    • 实际上现在一切正常。再次感谢。还没有遇到特殊字符问题,但如果我遇到了,我会回来查看这篇文章。保重!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 2021-06-16
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多