Проблема конкатенации nvarchar - PullRequest
2 голосов
/ 03 августа 2010

Я, вероятно, пытаюсь сделать что-то простое после работы со всеми сложными вещами, но кажется, что это вызывает у меня головную боль.Я пытаюсь объединить текст в переменную @strXml, которая является переменной nvarchar для создания элемента Xml, но @strXml возвращает ноль.Пожалуйста помоги.Я публикую свой код ниже.

DECLARE @strXml nvarchar(max) = ''
SET @strXml = '<PromoName>' + (Select PromoName From #Temp) + '</PromoName>' 
SET @strXml = @strXml + '<PromoDesc>' + (Select PromoDesc From #Temp) + '</PromoDesc>'
SET @strXml = @strXml + '<PromoCode>' + (Select PromoCode From #Temp) + '</PromoCode>' 
SET @strXml = @strXml + '<BeginDate>' + (Select Convert(nvarchar, BeginDate) From #Temp) + '</BeginDate>'
SET @strXml = @strXml + '<EndDate>' + (Select Convert(nvarchar, EndDate) From #Temp) + '</EndDate>'
SET @strXml = @strXml + '<RawHtml>' + (Select RawHtml From #Temp) + '</RawHtml>'
SET @strXml = @strXml + '<FocusPromoInd>' + Convert(nvarchar, 0) + '</FocusPromoInd>'
SET @strXml = @strXml + '<ParentPromoCode>' + (Select ParentPromoCode From #Temp) + '</ParentPromoCode>'
SET @strXml = @strXml + '<ActiveInd>' + (Select Case When ActiveInd=1 Then '1' Else '0' End From #Temp) + '</ActiveInd>'
SET @strXml = @strXml + '<AreaID>' + (Select Convert(nvarchar, AreaID) From #Temp) + '</AreaID>'
SET @strXml = '<PromoData><Promotion>' + @strXml + '</Promotion></PromoData>'
Select @strXml as strXML

И когда я запускаю последний запрос, он возвращает ноль.Даже в режиме отладки я не вижу @strXml, обновленный значением в каждой строке.Пожалуйста помоги!Спасибо.

Ответы [ 5 ]

5 голосов
/ 03 августа 2010

Одно из полей, которые вы объединяете, имеет значение null.

Каждый раз, когда вы объединяете строку и нулевое значение в SQL, результатом является значение null.

Вы можете использовать команду COALESCE дляисправить это:

declare @strXml nvarchar(max) = ''
set @strXml = '<PromoName>' + (select coalesce(PromoName, '') from #Temp) +
    '</PromoName>'
-- and so on
1 голос
/ 03 августа 2010

Как уже отмечали другие, конкатенация строки с NULL приводит к NULL. В SQL Server есть опция для управления этим, поэтому перед запросом следует указать SET CONCAT_NULL_YIELDS_NULL OFF.

1 голос
/ 03 августа 2010

Любое выражение, содержащее NULL, оценивается как NULL.Таким образом, один NULL в любом столбце уничтожит все остальные значения.Вы можете использовать функцию ISNULL, чтобы обойти эту проблему.Рассмотрите возможность структурирования кода следующим образом:

DECLARE @xml nvarchar(max)

SET @xml = 
(
    SELECT ISNULL(PromoName,'') AS PromoName
        , ISNULL(PromoDesc,'') AS PromoDesc
        , ISNULL(PromoCode,'') AS PromoCode
        --etc.
    FROM #Temp
    FOR XML RAW('Promotion'), ELEMENTS
)

В этом примере также используется простая версия предложения SQLServer FOR XML.Если вы переводите данные в строки XML в TSQL, я бы порекомендовал вам взглянуть на эту языковую функцию.Этот метод не применяется к другим платформам баз данных.

1 голос
/ 03 августа 2010

Если какое-либо из значений в конкатенации равно NULL, результирующая строка также равна NULL. Если вы просто хотели, чтобы значение NULL было пустым, вместо этого вы можете использовать одну из функций SQL NULL, чтобы вернуть пустую строку. Полный список поддерживаемых функций для различных механизмов SQL см. В W3Schools SQL NULL Functions .

1 голос
/ 03 августа 2010

Если вы объедините строку с нулем, результат будет нулевым.Таким образом, если только одно из полученных вами значений является нулевым, весь результат будет иметь нулевое значение.

Вы можете использовать isnull( ... , ''), чтобы превратить любое значение, которое может быть нулевым, в пустую строку.1004 *

Кроме того, вместо того, чтобы использовать множество выборок из одной таблицы, вы можете использовать один выбор:

select @strXml =
  '<PromoData><Promotion>' +
  '<PromoName>' + PromoName + '</PromoName>' +
  '<PromoCode>' + PromoCode + '</PromoCode>' +
  ...
  '<AreaID>' + convert(nvarchar, AreaID) + '</AreaID>'
  '</Promotion></PromoData>'
from #Temp
...