Sql server MsSQL xml解析为十进制
我正在用这个存储过程处理xmlSql server MsSQL xml解析为十进制,sql-server,xml,tsql,null,type-conversion,Sql Server,Xml,Tsql,Null,Type Conversion,我正在用这个存储过程处理xml select col.query('./AgreementId').value('.','uniqueidentifier') as [AgreementId], x.query('./GrossValue').value('.','decimal(19, 4)') as [GrossValue] into #AdvanceInvoices from @XML.nodes('/DataFromERP/CustomObjects/Ag
select
col.query('./AgreementId').value('.','uniqueidentifier') as [AgreementId],
x.query('./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)
问题是GrossValue,它可以为空
<GrossValue></GrossValue>
如何准备它以获得0.0而不是错误
编辑:
我想出了
CAST(COALESCE(NULLIF(ISNULL(x.query('./GrossValue').value('.','nvarchar(50)'),''),''),'0.0') as decimal(19,4)) as [GrossValue],
但是它非常难看您可以尝试从元素中获取VARCHAR值,使用to decimal,如果值为NULL,则使用ISNULL获取0.0
ISNULL(TRY_CAST(x.query('./GrossValue').value('.','VARCHAR(20)') AS DECIMAL(19,4)),.0) AS [GrossValue]
大概和我想象的一样难看。早在
TRY\u CAST
和TRY\u CONVERT
发明之前,就有一个XQuery
CAST:
DECLARE @SomeTable TABLE(ID INT IDENTITY, SomeXML XML);
INSERT INTO @SomeTable VALUES
(N'<DATA><SomeNumber>1</SomeNumber></DATA>') --integer
,(N'<DATA><SomeNumber>1.1</SomeNumber></DATA>') --decimal
,(N'<DATA><SomeNumber></SomeNumber></DATA>') --empty
,(N'<DATA><SomeNumber>abc</SomeNumber></DATA>') --invalid
,(N'<DATA><SomeNumber>.123</SomeNumber></DATA>') --short
SELECT t.SomeXML.value(N'/DATA[1]/SomeNumber[1]/text()[1] cast as xs:decimal?',N'decimal(19,4)')
FROM @SomeTable AS t
或者更简单,只是一个演员:
DECLARE @InvalidNumber VARCHAR(100)='123a'
,@ValidNumber VARCHAR(100)='123';
SELECT CAST(@InvalidNumber AS XML).value(N'. cast as xs:int?',N'int') AS InvalidNumber
,CAST(@ValidNumber AS XML).value(N'. cast as xs:int?',N'int') AS ValidNumber
这是可行的,但仅限于SQL Server 2012+(我这边的upvote)我们不得不等待您基于XQuery提出更好的解决方案:)+1
DECLARE @InvalidNumber VARCHAR(100)='123a'
,@ValidNumber VARCHAR(100)='123';
SELECT (SELECT @InvalidNumber FOR XML PATH(''),TYPE).value(N'. cast as xs:int?',N'int') AS InvalidNumber
,(SELECT @ValidNumber FOR XML PATH(''),TYPE).value(N'. cast as xs:int?',N'int') AS ValidNumber;
DECLARE @InvalidNumber VARCHAR(100)='123a'
,@ValidNumber VARCHAR(100)='123';
SELECT CAST(@InvalidNumber AS XML).value(N'. cast as xs:int?',N'int') AS InvalidNumber
,CAST(@ValidNumber AS XML).value(N'. cast as xs:int?',N'int') AS ValidNumber