Concatenación de cadenas de SQL Server con nulo


85

Estoy creando una columna calculada en campos de los cuales algunos son potencialmente nulos.

El problema es que si alguno de esos campos es nulo, toda la columna calculada será nula. Entiendo por la documentación de Microsoft que esto se espera y se puede desactivar mediante la configuración SET CONCAT_NULL_YIELDS_NULL. Sin embargo, no quiero cambiar este comportamiento predeterminado porque no conozco sus implicaciones en otras partes de SQL Server.

¿Hay alguna forma de que pueda verificar si una columna es nula y solo agregar su contenido dentro de la fórmula de columna calculada si no es nula?


2
La respuesta aceptada fue correcta en el momento en que se hizo la pregunta, pero para todos en SQL Server 2012 y posteriores (y que en esta etapa deberían ser todos) la respuesta de @ Martin-Smith es la mejor ya que maneja nulos automáticamente.
Dowlers

Respuestas:


142

Puedes usar ISNULL(....)

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

Si el valor de la columna / expresión es de hecho NULL, se utilizará en su lugar el segundo valor especificado (aquí: cadena vacía).


22
"Coalesce" es el nombre de la función estándar ANSI, pero ISNULL es más fácil de deletrear.
Philip Kelley

1
E ISNULL también parece ser un poco más rápido en SQL Server, por lo que si desea usarlo en una función que concatena cadenas en una columna calculada, puede renunciar al estándar ANSI y optar por la velocidad (consulte Adam Machanic: sqlblog.com / blogs / adam_machanic / archive / 2006/07/12 /… )
marc_s

Solo usé esta consulta Isnull (,), me ayudó mucho ya que estaba concatenando valores juntos y si uno de ellos era nulo, todo se volvió nulo también.
Sizons

Usar ISNULL()es una buena solución, pero a partir de SQL Server 2012 en adelante, también puede usar la CONCATfunción para obtener el mismo resultado:CONCAT(@Column1, @Column2)
Muhammad Musavi

2
Vale la pena señalar aquí que si desea cambiar nullpor algo que no sea una cadena vacía, es decir IsNull(@Column1, 'NULLVALUE'), con IsNullla longitud de la cadena de reemplazo se limita a la longitud de la columna que está reemplazando, mientras que no lo estáCoalesce
Jamie

58

Desde SQL Server 2012, todo esto es mucho más fácil con la CONCATfunción.

Se trata NULLcomo una cadena vacía

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


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

¡Gracias! ¡¡Esto era lo que necesitaba !!
Shiva

Para versiones anteriores, obtienes "'CONCAT' no es un nombre de función integrado reconocido", así que usa COALESCE
Savage

3
@Savage - COALESCE no funcionará porque no se concatena, solo devuelve el primer argumento no nulo
codeulike

30

Utilice COALESCE . En lugar de your_columnusar COALESCE(your_column, ''). Esto devolverá la cadena vacía en lugar de NULL.


OP quiere cuerdas concat juntos, se unen no hará que
codeulike

12

Utilizar

SET CONCAT_NULL_YIELDS_NULL  OFF 

y la concatenación de valores nulos en una cadena no dará como resultado un valor nulo.

Tenga en cuenta que esta es una opción obsoleta, evite usar. Consulte la documentación para obtener más detalles.


11

También puede usar CASE: mi código a continuación verifica tanto valores nulos como cadenas vacías, y agrega un separador solo si hay un valor a seguir:

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

Solo quería contribuir con esto si alguien estuviera buscando ayuda para agregar separadores entre las cadenas, dependiendo de si un campo es NULL o no.

Entonces, en el ejemplo de creación de una dirección de una línea a partir de campos separados

Dirección 1 , Dirección 2 , Address3 , Ciudad , Código Postal

en mi caso, tengo la siguiente columna calculada que parece estar funcionando como quiero:

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

¡Espero que ayude a alguien!


Hay bastantes corchetes anidados redundantes que podrían eliminarse. Otro consejo es que también puede eliminar la declaración del caso como si la dirección1 fuera nula, toda la expresión se evaluará como nula (aunque tener la declaración del caso llama la atención de que esto puede suceder)
Alternador


1

También tuve muchos problemas con esto. No pude hacerlo funcionar usando los ejemplos de casos anteriores, pero esto hace el trabajo por mí:

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

Reemplazar corrige los espacios dobles causados ​​por la concatenación de espacios simples sin nada entre ellos. r / ltrim elimina los espacios en los extremos.


0

En el servidor 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.

Código detrás:

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

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

0

Este ejemplo le ayudará a manejar varios tipos mientras crea declaraciones de inserció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'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.