yo me encontré con esta pregunta, y en última instancia una respuesta, mientras mira a un problema similar con números enteros. A pesar de la demora desde la última respuesta, agregaré aquí en caso de que ayude a alguien más en el futuro.
En primer lugar su respuesta básica:
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
En XQuery se puede convertir el valor a un tipo de esquema XML estándar, que luego se maneja correctamente por SQL Server.
TEN EN CUENTA: el valor "numérico" predeterminado en SQL Server no tiene ningún lugar decimal (escala de "0")! Es probable que la intención de hacer algo más como:
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
(no se puede obtener SQL Server para inferir la precisión o escala desde el valor devuelto por el XML, debe especificar explícitamente)
Por último, el actual tema que en lo personal necesario para hacer frente era casi exactamente lo mismo, excepto que estaba tratando con números enteros, que también luchan con la representación XML de "0" double
valores:
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
ACTUALIZACIÓN: El problema con la solución de manejo decimal que publiqué arriba (convirtiendo a decimal en XQuery antes de que SQL llegue a analizar el valor) es que la agregación realmente ocurre con el tipo de datos flotante (doble) asumido/inferido. Si los valores que ha almacenado en su Xml requieren un alto grado de precisión, esto puede ser lo que no debe hacer: la agregación de coma flotante puede resultar en una pérdida de datos. EG aquí perdemos el último dígito del número que estamos sumando:
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
(que sale a "2000000000000000000000000000", lo que está mal)
Este problema se aplica igualmente a otros enfoques que aquí se ofrecen, tales como explícitamente leyendo el valor como "flotante" en T-SQL.
Para evitar esto, esta es una opción final que utiliza una expresión XQuery FLWOR para establecer el tipo de datos antes de la operación de agregación. En este caso, la agregación se produce correctamente, y tenemos el valor sumado correcta (a la vez que el manejo de los valores "0" si/cuando se producen):
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
(sale a "2000000000000000000000000002", el valor correcto)
Parece que sum (/ List/value) devuelve un flotante "0.0E0" cuando la suma es cero y ese número no se puede convertir a numérico. ¿Alguna idea de por qué veo este comportamiento? –