Принятое решение работает, но это можно сделать лучше:
- XML содержит одно десятичное значение, один пустой узел и один узел с пробелом.
- Добавьте узел с помощьюнекалиброванное значение "привет", чтобы проверить методы с этим тоже.
DECLARE @xml XML=N'<a>123.456</a>
<a/>
<a> </a>';
--add one more with a non-castable value
-- <a>hello</a>';
- Подход "постановка": прочитайте строку и продолжите извне
SELECT a.value('text()[1]','nvarchar(max)') worksInAnyCase
FROM @xml.nodes('/a') A(a)
-Подход с безопасным типом завершится неудачей для недесятичных знаков
SELECT a.value('text()[1]','decimal(6,3)') FailsForHello
FROM @xml.nodes('/a') A(a)
- здесь может помочь приведение XQuery
SELECT a.value('text()[1] cast as xs:decimal?','decimal(6,3)') WorksImplicitly
FROM @xml.nodes('/a') A(a)
- TRY_CAST также помогает (требуется v2012 +)
SELECT TRY_CAST(a.value('text()[1]','nvarchar(max)') AS DECIMAL(6,3)) castedIfPossible
FROM @xml.nodes('/a') A(a)
- NULLIF тоже может помочь, но привет пройдет мимо
SELECT NULLIF(a.value('text()[1]','nvarchar(max)'),'') NullForBlanks
FROM @xml.nodes('/a') A(a)
- Принятое решение не работает и для приветствия
SELECT CASE WHEN ISNULL(a.value('text()[1]', 'VARCHAR(15)'),'') = '' THEN NULL ELSE CAST(a.value('text()[1]', 'VARCHAR(15)') AS decimal(6,3)) END FailsForHello
FROM @xml.nodes('/a') A(a)
Моим любимым был кастом XQuery .. .