Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server MsSQL xml解析为十进制_Sql Server_Xml_Tsql_Null_Type Conversion - Fatal编程技术网

Sql server MsSQL xml解析为十进制

Sql 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

我正在用这个存储过程处理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/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