整数に関する同様の問題を見ているときに、この質問に出くわし、最終的には答えになりました。最後の回答からの遅れにもかかわらず、将来他の誰かに役立つ場合に備えて、ここに追加します。
最初にあなたの基本的な答え:
select xml.value('xs:decimal(sum(/List/value))', 'numeric') sum
from (select cast('<List><value>0</value><value>0</value></List>' as xml) xml) a
XQuery では、値を標準の XML スキーマ型にキャストできます。これは、SQL Server によって正しく処理されます。
注意: SQL Server のデフォルトの「数値」には小数点以下の桁数がありません (位取りは「0」)。おそらく、次のようなことをするつもりでした:
select xml.value('xs:decimal(sum(/List/value))', 'numeric(20,5))') sum
from (select cast('<List><value>0</value><value>0</value></List>' as xml) xml) a
(SQL Server に Xml から返された値から精度またはスケールを推測させることはできません。明示的に指定する必要があります)
double
最後に、私が個人的に対処する必要がある実際の問題は、「0」値の xml 表現にも苦労している整数を扱っていたことを除いて、ほぼ同じでした。
select xml.value('xs:int(sum(/List/value))', 'int') sum
from (select cast('<List><value>0</value><value>0</value></List>' as xml) xml) a
更新:私が上に投稿した 10 進数処理ソリューション (SQL が値を解析する前に XQuery で 10 進数に変換する) の問題は、(想定/推測された) 浮動小数点 (double) データ型で集計が実際に行われることです。Xml に保存した値に高度な精度が必要な場合、実際にはこれを行うのは間違っている可能性があります。浮動小数点の集計により、実際にはデータが失われる可能性があります。EG ここでは、合計している数値の最後の桁を失います。
select xml.value('xs:decimal(sum(/List/value))', 'numeric(28, 0)') sum
from (select cast('<List>
<value>1000000000000000000000000001</value>
<value>1000000000000000000000000001</value>
</List>' as xml) xml) a
(「200000000000000000000000000」と出てきますが、これは間違っています)
この問題は、T-SQL で値を "float" として明示的に読み取るなど、ここで提供される他のアプローチにも同様に適用されます。
これを回避するために、集計操作の前にXQuery FLWOR 式を使用してデータ型を設定する最後のオプションを次に示します。この場合、集計は正しく行われ、正しい合計値が得られます (発生した場合は "0" 値も処理します)。
select xml.value('sum(for $r in /List/value return xs:decimal($r))', 'numeric(28, 0)') sum
from (select cast('<List>
<value>1000000000000000000000000001</value>
<value>1000000000000000000000000001</value>
</List>' as xml) xml) a
(「200000000000000000000000002」、正しい値になります)