Как преобразовать значение типа XML SQL Server (xsi:nil) DateTime в null

есть ли способ запросить тип XML SQL Server, чтобы для элемента с xsi:nil="true", возвращает null вместо значения datetime по умолчанию, которое является 1900-01-01 00:00:00.000?

вот фрагмент кода

declare @data xml
set @data = 
    '<DOD   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:nil="true" />'
select  Value1 = @data.value('/DOD[1]', 'datetime'),
        Value2 = IsNull(@data.value('/DOD[1]', 'datetime'), 'NOT NULL?'),
        Value3 = nullif(@data.value('/DOD[1]', 'datetime'), '1900-01-01')

Value1 & Value2 оба возвращает 1900-01-01 00:00:00.000. Есть ли способ вернуть null вместо этого? без использования nullif?

5 ответов


" default " datetime вызвано приведением пустой строки, которая равна "нулю", что дает 01 января 1900.

Итак: уберите строку, затем CAST

declare @data xml

set @data = 
        '<DOD   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                        xsi:nil="true" />'

select
    Value1 = CAST(NULLIF(@data.value('/DOD[1]', 'varchar(30)'), '') AS datetime)

просто:

declare @data xml

set @data = 
        '<DOD   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                        xsi:nil="true" />'

select
    Value1 = @data.value('(/DOD/text())[1]', 'varchar(30)')

вы также можете явно проверить nil так:

declare @data xml

set @data = '<DOD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />'

select Value1 = @data.value('(/DOD[not(@xsi:nil eq "true")])[1]', 'datetime')

этот случай может быть не для каждого

умный способ сделать это-удалить узел DOD из XML. Итак, какой бы узел вы ни хотели иметь null в результирующем наборе, просто удалите этот узел при добавлении его в XML.

таким образом, ниже также приведет к нулю:

declare @data xml

set @data = '<Test> </Test>'

select  Value1 = @data.value('(/DOD/text())[1]', 'varchar(30)')

в приведенном выше примере видно, что нет узла DOD, следовательно, это приведет к нулевому значению


Я знаю, что этот поток был мертв некоторое время, но я думаю, что этот способ немного проще:

SELECT value1 = NULLIF(@data.value('/DOD[1]', 'datetime'), '')

строковое значение из строки xml вычисляется первым, и если оно пустое, станет нулевым datetime.