MsSQL解析XML空GrossValue转decimal报错,求优雅解决方案
解决XML中空GrossValue转换为decimal报错的简化方案
兄弟,我懂你这糟心的问题——当XML里的<GrossValue>是空标签(<GrossValue></GrossValue>)时,直接转换为decimal会抛出“将数据类型nvarchar转换为numeric时出错”的错误,而且你自己想到的嵌套函数写法确实太繁琐了。这里有两个简洁得多的解决方案:
方案1:用TRY_CAST简化空值处理
如果你使用的是SQL Server 2012及以上版本,TRY_CAST是最省心的选择。它会尝试转换值,一旦转换失败(比如空字符串)就返回NULL,再用ISNULL把NULL替换成0.0即可:
ISNULL(TRY_CAST(x.query('./GrossValue').value('.','nvarchar(50)') AS decimal(19,4)), 0.0) AS [GrossValue]
这个写法比你原来的多层嵌套精简太多,逻辑也更清晰。
方案2:在XQuery阶段直接处理空值
如果你想把空值判断逻辑放在XML查询里,可以用XQuery的fn:empty()函数直接检测标签内容是否为空,返回0或者实际值:
x.query('if (empty(./GrossValue/text())) then 0 else ./GrossValue').value('.','decimal(19,4)') AS [GrossValue]
这种方式不需要先转成字符串再处理,所有逻辑都在XQuery里完成,适合更关注XML查询阶段处理的场景。
修改后的完整存储过程示例
用方案1的完整代码:
SELECT col.query('./AgreementId').value('.','uniqueidentifier') AS [AgreementId], ISNULL(TRY_CAST(x.query('./GrossValue').value('.','nvarchar(50)') AS decimal(19,4)), 0.0) AS [GrossValue] INTO #AdvanceInvoices FROM @XML.nodes('/DataFromERP/CustomObjects/Agreements/Agreement') AS ref(col) CROSS APPLY ref.col.nodes('AdvanceInvoices/AdvanceInvoice') AS T(x)
用方案2的完整代码:
SELECT col.query('./AgreementId').value('.','uniqueidentifier') AS [AgreementId], x.query('if (empty(./GrossValue/text())) then 0 else ./GrossValue').value('.','decimal(19,4)') AS [GrossValue] INTO #AdvanceInvoices FROM @XML.nodes('/DataFromERP/CustomObjects/Agreements/Agreement') AS ref(col) CROSS APPLY ref.col.nodes('AdvanceInvoices/AdvanceInvoice') AS T(x)
内容的提问来源于stack exchange,提问作者Dela
相关产品推荐
相关产品推荐

