Конкатенація рядків SQL Server з нулем


85

Я створюю обчислюваний стовпець між полями, деякі з яких потенційно нульові.

Проблема полягає в тому, що якщо будь-яке з цих полів є нульовим, весь обчислюваний стовпець буде нульовим. З документації корпорації Майкрософт я розумію, що це очікується, і його можна вимкнути за допомогою налаштування SET CONCAT_NULL_YIELDS_NULL. Однак там я не хочу змінювати цю поведінку за замовчуванням, оскільки я не знаю її наслідків для інших частин SQL Server.

Чи є спосіб для мене просто перевірити, чи є стовпець нульовим, і додати його вміст до обчислюваної формули стовпця, лише якщо він не нульовий?


2
Прийнята відповідь була правильною на той момент, коли було задано питання, але для всіх на SQL Server 2012 та пізніших версіях (і що цей етап повинен бути всім) відповідь @ Martin-Smiths є найкращою, оскільки вона обробляє нулі автоматично.
Dowlers

Відповіді:


142

Можна використовувати ISNULL(....)

SET @Concatenated = ISNULL(@Column1, '') + ISNULL(@Column2, '')

Якщо значення стовпця / виразу справді NULL, тоді замість нього буде використано друге вказане значення (тут: порожній рядок).


22
"Coalesce" - це стандартна назва функції ANSI, але ISNULL легше пишеться.
Філіп Келлі,

1
І ISNULL, здається, теж трохи швидший на SQL Server - тому, якщо ви хочете використовувати його у функції, яка об'єднує рядки в обчислюваний стовпець, ви можете відмовитися від стандарту ANSI і вибрати швидкість (див. Адам Маханік : sqlblog.com / blogs / adam_machanic / archive / 2006/07/12 /… )
marc_s

Щойно використав цей запит Isnull (,), він сильно накрутився, оскільки я об'єднував значення разом, і якщо одне з них було нульовим, все теж стало нульовим.
Сізон

Використання ISNULL()є хорошим рішенням, але з SQL Server 2012, ви також можете використовувати CONCATфункцію, щоб отримати той самий результат:CONCAT(@Column1, @Column2)
Мухаммад Мусаві

2
Тут варто зазначити, що якщо ви хочете помінятись nullна щось інше, ніж порожній рядок, тобто IsNull(@Column1, 'NULLVALUE')із IsNullзаміною довжина рядка обмежена довжиною стовпця, який він замінює, тоді як це не такCoalesce
Джеймі

58

З SQL Server 2012 це набагато простіше завдяки CONCATфункції.

Це трактується NULLяк порожній рядок

DECLARE @Column1 VARCHAR(50) = 'Foo',
        @Column2 VARCHAR(50) = NULL,
        @Column3 VARCHAR(50) = 'Bar';


SELECT CONCAT(@Column1,@Column2,@Column3); /*Returns FooBar*/

Дякую! Це було те, що мені потрібно !!
Шива

Для старих версій ви отримуєте "" CONCAT "не є розпізнаним вбудованим ім'ям функції", тому використовуйте COALESCE
Savage

3
@Savage - COALESCE не працює, оскільки він не об'єднується, він просто повертає перший ненульовий аргумент
codeulike

30

Використовуйте COALESCE . Замість your_columnвикористання COALESCE(your_column, ''). Це поверне порожній рядок замість NULL.


OP хоче поєднувати рядки разом, COALESCE не робить цього
кодек, як

12

Використовуйте

SET CONCAT_NULL_YIELDS_NULL  OFF 

і об'єднання нульових значень у рядок не призведе до нульового значення.

Зверніть увагу, що це застарілий варіант, уникайте використання. Детальніше див. У документації .


11

Ви також можете використовувати CASE - мій код нижче перевіряє як нульові значення, так і порожні рядки, і додає сепаратор, лише якщо є значення, яке слід дотримуватися:

SELECT OrganisationName, 
'Address' = 
CASE WHEN Addr1 IS NULL OR Addr1 = '' THEN '' ELSE Addr1 END + 
CASE WHEN Addr2 IS NULL OR Addr2 = '' THEN '' ELSE ', ' + Addr2 END + 
CASE WHEN Addr3 IS NULL OR Addr3 = '' THEN '' ELSE ', ' + Addr3 END + 
CASE WHEN County IS NULL OR County = '' THEN '' ELSE ', ' + County END 
FROM Organisations 

8

Я просто хотів внести це, якщо хтось шукає допомоги з додаванням роздільників між рядками, залежно від того, чи є поле NULL чи ні.

Отже, на прикладі створення однорядкової адреси з окремих полів

Адреса1 , Адреса2 , Адреса3 , Місто , Поштовий Індекс

у моєму випадку у мене є така розрахункова колонка, яка, здається, працює так, як я хочу:

case 
    when [Address1] IS NOT NULL 
    then (((          [Address1]      + 
          isnull(', '+[Address2],'')) +
          isnull(', '+[Address3],'')) +
          isnull(', '+[City]    ,'')) +
          isnull(', '+[PostCode],'')  
end

Сподіваюся, це комусь допомагає!


Там досить багато зайвого вкладеного брекетингу, який можна видалити. Інша порада полягає в тому, що ви також можете видалити випадок case, так як якщо address1 має значення null, весь вираз оцінить як null (хоча наявність виписки справи звертає увагу, що це може статися)
Генератор змінного


1

У мене теж із цим було багато клопоту. Не вдалося змусити його працювати на прикладах вище, але це робить роботу для мене:

Replace(rtrim(ltrim(ISNULL(Flat_no, '') + 
' ' + ISNULL(House_no, '') + 
' ' + ISNULL(Street, '') + 
' ' + ISNULL(Town, '') + 
' ' + ISNULL(City, ''))),'  ',' ')

Replace виправляє подвійні пробіли, спричинені об'єднанням одинарних пробілів, між якими нічого немає. r / ltrim позбавляється від будь-яких пробілів на кінцях.


0

На сервері Sql:

insert into Table_Name(PersonName,PersonEmail) values(NULL,'xyz@xyz.com')

PersonName is varchar(50), NULL is not a string, because we are not passing with in single codes, so it treat as NULL.

Код позаду:

string name = (txtName.Text=="")? NULL : "'"+ txtName.Text +"'";
string email = txtEmail.Text;

insert into Table_Name(PersonName,PersonEmail) values(name,'"+email+"')

0

Цей приклад допоможе вам обробляти різні типи під час створення операторів вставки

select 
'insert into doc(Id, CDate, Str, Code, Price, Tag )' + 
'values(' +
      '''' + convert(nvarchar(50), Id) + ''',' -- uniqueidentifier
    + '''' + LEFT(CONVERT(VARCHAR, CDate, 120), 10) + ''',' -- date
    + '''' + Str+ ''',' -- string
    + '''' + convert(nvarchar(50), Code)  + ''',' -- int
    + convert(nvarchar(50), Price) + ',' -- decimal
    + '''' + ISNULL(Tag, '''''') + '''' + ')'  -- nullable string

 from doc
 where CDate> '2019-01-01 00:00:00.000'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.