Null ile SQL Server String Birleştirme


86

Bazılarının potansiyel olarak boş olduğu alanlar arasında hesaplanmış bir sütun oluşturuyorum.

Sorun şu ki, bu alanlardan herhangi biri boşsa, hesaplanan sütunun tamamı boş olacaktır. Microsoft belgelerinden bunun beklendiğini ve SET CONCAT_NULL_YIELDS_NULL ayarıyla kapatılabileceğini anlıyorum. Ancak, orada bu varsayılan davranışı değiştirmek istemiyorum çünkü bunun SQL Server'ın diğer bölümleri üzerindeki etkilerini bilmiyorum.

Bir sütunun boş olup olmadığını kontrol etmenin ve yalnızca boş değilse içeriğini hesaplanan sütun formülüne eklememin bir yolu var mı?


2
Kabul edilen yanıt, sorunun sorulduğu anda doğruydu, ancak SQL Server 2012 ve sonraki sürümlerdeki herkes için (ve bu aşama herkes olmalı) @ Martin-Smiths yanıtı, boşları otomatik olarak işlediği için en iyisidir.
Dowlers

Yanıtlar:


144

Kullanabilirsiniz ISNULL(....)

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

Sütunun / ifadenin değeri gerçekten NULL ise, bunun yerine belirtilen ikinci değer (burada: boş dize) kullanılacaktır.


23
"Birleştirme" ANSI standardı işlev adıdır, ancak ISNULL'un hecelenmesi daha kolaydır.
Philip Kelley

1
Ve ISNULL, SQL Server'da da biraz daha hızlı görünüyor - bu nedenle, dizeleri hesaplanmış bir sütuna birleştiren bir işlevde kullanmak istiyorsanız, ANSI standardından vazgeçebilir ve hızı tercih edebilirsiniz (bkz. Adam Machanic : sqlblog.com / blogs / adam_machanic / arşiv / 2006/07/12 /… )
marc_s

Sadece bu Isnull (,) sorgusunu kullandım, değerleri bir araya getirirken çok şey yaptı ve bunlardan biri boşsa, her şey de boş oldu.
Sizons

Kullanmak ISNULL()iyi bir çözümdür, ancak SQL Server 2012'den itibaren CONCATaynı sonucu elde etmek için işlevi de kullanabilirsiniz :CONCAT(@Column1, @Column2)
Muhammad Musavi

2
Bu takas istiyorsanız burada belirtmek gerekir nullyani boş bir dize dışındaki bir şey için IsNull(@Column1, 'NULLVALUE')birlikte IsNullyedek dizi uzunluğu it 'değiştiriyor sütunun uzunluğu ile sınırlıdır onunla değilken,Coalesce
Jamie

59

SQL Server 2012'den itibaren bu, CONCATişlevle çok daha kolaydır .

NULLBoş dize olarak davranır

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


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

Daha eski sürümler için "'CONCAT' tanınan bir yerleşik işlev adı değil" alırsınız, bu nedenle COALESCE
Savage

3
@Savage - COALESCE çalışmaz çünkü bitiştirilmez, sadece ilk boş olmayan argümanı döndürür
codeulike


12

Kullanım

SET CONCAT_NULL_YIELDS_NULL  OFF 

ve boş değerlerin bir dizeye birleştirilmesi boş değerle sonuçlanmaz.

Lütfen bunun kullanımdan kaldırılmış bir seçenek olduğunu unutmayın, kullanmaktan kaçının. Daha fazla ayrıntı için belgelere bakın.


11

Ayrıca CASE'i de kullanabilirsiniz - aşağıdaki kodum hem boş değerleri hem de boş dizeleri kontrol eder ve yalnızca izlenecek bir değer varsa bir ayırıcı ekler:

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

Bir alanın NULL olup olmadığına bağlı olarak dizeler arasına ayırıcı ekleme konusunda yardım arayan biri için buna katkıda bulunmak istedim .

Dolayısıyla, ayrı alanlardan tek satırlık bir adres oluşturma örneğinde

Adres1 , Adres2 , address3 , İl , posta kodu

benim durumumda, istediğim gibi çalışıyor gibi görünen şu Hesaplanmış Sütuna sahibim:

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

Umarım bu birine yardımcı olur!


Orada kaldırılabilecek oldukça fazla iç içe geçmiş parantez var. Başka bir ipucu da, case ifadesini adres1 boşmuş gibi kaldırabilirsiniz, tüm ifade boş olarak değerlendirilir (ancak case ifadesine sahip olmak bunun olabileceğine dikkat
Alternator


1

Bununla ben de çok sıkıntı yaşadım. Yukarıdaki vaka örneklerini kullanarak çalıştırılamadı, ancak bu benim için işi yapıyor:

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

Değiştir, aralarında hiçbir şey olmayan tek boşlukların birleştirilmesinden kaynaklanan çift boşlukları düzeltir. r / ltrim uçlardaki boşluklardan kurtulur.


0

Sql Sunucusunda:

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.

Arkasındaki Kod:

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

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

0

Bu örnek, ekleme deyimleri oluştururken çeşitli türleri işlemenize yardımcı olacaktır

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'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.