You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server读取XML生成表返回NULL值问题求助

SQL Server解析XML返回全NULL值问题解决

尝试在SQL Server中解析从MOEX获取的债券历史数据XML,XML结构如下:

<document>
    <data>
        <metadata>
            ...
        </metadata>
        <rows>
            <row TRADEDATE="2023-04-17" SHORTNAME="ВТБРКС01" SECID="RU000A1032P1" YIELDCLOSE = "12.93"  LEGALCLOSEPRICE="91.33" VOLUME="70824"/>
            <row .../>
            ...
        </rows>
    </data>
</document>

运行以下SQL代码后,返回的所有字段均为NULL:

USE MoexTest
GO

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM history

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT secid, shortname, legalcloseprice, yieldclose, volume
FROM OPENXML(@hDoc, 'document/data/rows/row')
WITH 
(
secid [nvarchar](50) '@secid',
shortname [nvarchar] (10) '@shortname',
legalcloseprice [float] '@legalcloseprice',
yieldclose [float] '@yieldclose',
volume [integer] '@volume'
)

EXEC sp_xml_removedocument @hDoc
GO

实际返回结果:

secidshortnamelegalclosepriceyieldclosevolume
NULLNULLNULLNULLNULL
NULLNULLNULLNULLNULL
...............

期望返回结果:

secidshortnamelegalclosepriceyieldclosevolume
RU000A1032P1ВТБРКС0191.3312.9370824
RU000A1032P1ВТБРКС0191.312.9531166
...............

问题原因

SQL Server的OPENXML对XML属性名大小写敏感,你在WITH子句中使用的是小写属性名(如@secid),但XML中的属性是大写形式(如SECID),导致无法匹配到对应值,所以返回NULL。

解决方法

方法1:修正OPENXML的属性名大小写

将WITH子句中的属性名改为与XML中一致的大写形式:

USE MoexTest
GO

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM history

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT secid, shortname, legalcloseprice, yieldclose, volume
FROM OPENXML(@hDoc, 'document/data/rows/row')
WITH 
(
secid [nvarchar](50) '@SECID',
shortname [nvarchar](10) '@SHORTNAME',
legalcloseprice [float] '@LEGALCLOSEPRICE',
yieldclose [float] '@YIELDCLOSE',
volume [integer] '@VOLUME'
)

EXEC sp_xml_removedocument @hDoc
GO

方法2:使用SQL Server原生XML方法(推荐)

相比旧的OPENXML,SQL Server原生XML方法更简洁且无内存泄漏风险,直接用.value()提取属性:

USE MoexTest
GO

SELECT 
    x.value('@SECID', 'nvarchar(50)') AS secid,
    x.value('@SHORTNAME', 'nvarchar(10)') AS shortname,
    x.value('@LEGALCLOSEPRICE', 'float') AS legalcloseprice,
    x.value('@YIELDCLOSE', 'float') AS yieldclose,
    x.value('@VOLUME', 'integer') AS volume
FROM history
CROSS APPLY XMLData.nodes('/document/data/rows/row') AS t(x)
GO

说明

  • 方法2无需调用sp_xml_preparedocument和sp_xml_removedocument,是SQL Server处理XML的推荐方案。
  • 确保history表中的XMLData字段类型为XML,若为字符串类型需先转换为XML格式。

内容的提问来源于stack exchange,提问作者konstantintre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:24:58