带Null的SQL Server字符串串联


85

我正在跨字段创建计算列,其中某些字段可能为空。

问题是,如果这些字段中的任何一个为空,则整个计算列将为空。我从Microsoft文档中了解到这是可以预期的,可以通过设置SET CONCAT_NULL_YIELDS_NULL将其关闭。但是,我不想更改此默认行为,因为我不知道它对SQL Server其他部分的影响。

有没有一种方法可以让我检查列是否为空,如果列不为空,则仅将其内容追加到计算列公式中?


2
接受的答案在提出问题时是正确的,但是对于SQL Server 2012及更高版本上的每个人(这个阶段应该是每个人),@ Martin-Smiths的答案都是最佳的,因为它可以自动处理空值。
勒斯

Answers:


142

您可以使用 ISNULL(....)

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

如果column / expression的值确实为NULL,则将使用指定的第二个值(此处为空字符串)代替。


22
“ Coalesce”是ANSI标准的函数名称,但是ISNULL更容易拼写。
菲利普·凯利2010年

1
而且,在SQL Server上,ISNULL似乎也要快一些-因此,如果要在将字符串连接到计算列中的函数中使用它,则可以放弃ANSI标准并选择速度(请参阅Adam Machanic:sqlblog.com / blogs / adam_machanic / archive / 2006/07/12 /…
marc_s

刚使用此Isnull(,)查询,当我将值串联在一起时,它会发生很多变化,如果其中之一为null,则所有内容也将变为null。
Sizons '16

使用ISNULL()是一个很好的解决方案,但是从SQL Server 2012起,您还可以使用CONCAT函数来获得相同的结果:CONCAT(@Column1, @Column2)
Mohammad Musavi

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无法工作,因为它没有连接,它仅返回第一个非null参数
codeulike


12

使用

SET CONCAT_NULL_YIELDS_NULL  OFF 

并且将null值连接到字符串不会导致null。

请注意,这是不建议使用的选项,请避免使用。有关更多详细信息,请参见文档


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(尽管有case语句确实引起了注意,这可能会发生)
Alternator


1

我对此也有很多麻烦。使用上面的案例无法使它正常工作,但这对我有用:

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

“替换”可纠正由于连接单个空格而在它们之间没有任何空格而导致的双精度空格。r / ltrim消除了结尾处的任何空格。


0

在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.

背后的代码:

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'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.