Nối chuỗi SQL Server với Null


85

Tôi đang tạo một cột được tính toán trên các trường trong đó một số trường có khả năng là rỗng.

Vấn đề là nếu bất kỳ trường nào trong số đó là null, thì toàn bộ cột được tính toán sẽ là null. Tôi hiểu từ tài liệu của Microsoft rằng điều này được mong đợi và có thể được tắt thông qua cài đặt SET CONCAT_NULL_YIELDS_NULL. Tuy nhiên, ở đó tôi không muốn thay đổi hành vi mặc định này vì tôi không biết ý nghĩa của nó trên các phần khác của SQL Server.

Có cách nào để tôi chỉ kiểm tra xem một cột có rỗng hay không và chỉ nối nội dung của nó vào trong công thức cột đã tính nếu nó không phải là null?


2
Câu trả lời được chấp nhận là đúng vào thời điểm câu hỏi được hỏi nhưng đối với tất cả mọi người trên SQL Server 2012 trở về sau (và giai đoạn này nên là tất cả mọi người) câu trả lời @ Martin-Smiths là tốt nhất vì nó tự động xử lý null.
Dowlers

Câu trả lời:


142

Bạn có thể dùng ISNULL(....)

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

Nếu giá trị của cột / biểu thức thực sự là NULL, thì giá trị thứ hai được chỉ định (ở đây: chuỗi trống) sẽ được sử dụng thay thế.


22
"Coalesce" là tên hàm tiêu chuẩn ANSI, nhưng ISNULL dễ đánh vần hơn.
Philip Kelley

1
Và ISNULL dường như cũng nhanh hơn một chút trên SQL Server - vì vậy nếu bạn muốn sử dụng nó trong một hàm nối các chuỗi vào một cột được tính toán, bạn có thể bỏ qua tiêu chuẩn ANSI và chọn tốc độ (xem Adam Machanic: sqlblog.com / blogs / adam_machanic / archive / 2006/07/12 /… )
marc_s

Chỉ cần sử dụng truy vấn Isnull (,) này, nó rất nhiều khi tôi nối các giá trị với nhau và nếu một trong số chúng là null thì mọi thứ cũng trở thành null.
Sizons

Sử dụng ISNULL()được một giải pháp tốt nhưng từ SQL Server 2012, bạn cũng có thể sử dụng CONCATchức năng để có được kết quả tương tự:CONCAT(@Column1, @Column2)
Muhammad Musavi

2
Nó đáng chú ý ở đây là nếu bạn muốn trao đổi nullmột cái gì đó khác hơn là một chuỗi rỗng, nghĩa là IsNull(@Column1, 'NULLVALUE'), với IsNullchiều dài chuỗi thay thế được giới hạn độ dài của cột nó thay thế, trong khi nó không phải là vớiCoalesce
Jamie

58

Từ SQL Server 2012, điều này dễ dàng hơn nhiều với CONCAThàm.

Nó được coi NULLlà chuỗi rỗng

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


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

Cảm ơn! Đây là những gì tôi cần !!
Shiva

Đối với các phiên bản cũ hơn, bạn nhận được " 'CONCAT' được không phải là một công nhận built-in tên hàm", do đó sử dụng liên hiệp
Savage

3
@Savage - liên hiệp sẽ không làm việc bởi vì nó không concatenate, nó chỉ trả về đối số null phi đầu tiên
codeulike

30

Sử dụng COALESCE . Thay vì your_columnsử dụng COALESCE(your_column, ''). Điều này sẽ trả về chuỗi trống thay vì NULL.


OP muốn chuỗi concat với nhau, liên hiệp wont làm điều đó
codeulike

12

Sử dụng

SET CONCAT_NULL_YIELDS_NULL  OFF 

và việc nối các giá trị null vào một chuỗi sẽ không dẫn đến null.

Xin lưu ý rằng đây là một tùy chọn không được dùng nữa, hãy tránh sử dụng. Xem tài liệu để biết thêm chi tiết.


11

Bạn cũng có thể sử dụng CASE - mã của tôi bên dưới kiểm tra cả giá trị null và chuỗi rỗng, đồng thời chỉ thêm bộ phân tách nếu có giá trị để theo dõi:

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

Tôi chỉ muốn đóng góp điều này nếu ai đó đang tìm kiếm sự trợ giúp về việc thêm dấu phân cách giữa các chuỗi, tùy thuộc vào trường có phải là NULL hay không.

Vì vậy, trong ví dụ về tạo địa chỉ một dòng từ các trường riêng biệt

Address1 , Address2 , Address3 , thành phố , mã bưu điện

trong trường hợp của tôi, tôi có Cột được Tính toán sau đây dường như đang hoạt động như tôi muốn:

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

Hy vọng rằng sẽ giúp một ai đó!


Có khá nhiều dấu ngoặc nhọn lồng nhau thừa có thể được loại bỏ ở đó. Một mẹo khác là bạn cũng có thể xóa câu lệnh trường hợp như thể address1 là null, toàn bộ biểu thức sẽ đánh giá thành null (mặc dù có câu lệnh trường hợp thu hút sự chú ý rằng điều này có thể xảy ra)
Alternator


1

Tôi cũng gặp rất nhiều rắc rối với việc này. Không thể làm cho nó hoạt động bằng cách sử dụng các ví dụ trường hợp ở trên, nhưng điều này thực hiện công việc cho tôi:

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

Thay thế sửa chữa các khoảng trắng gây ra bởi việc nối các khoảng trắng đơn mà không có gì giữa chúng. r / ltrim loại bỏ bất kỳ khoảng trắng nào ở cuối.


0

Trong Sql Server:

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.

Mã ẩn:

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

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

0

Ví dụ này sẽ giúp bạn xử lý các kiểu khác nhau trong khi tạo các câu lệnh chèn

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'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.