Concaténation de chaînes SQL Server avec Null

85

Je crée une colonne calculée sur des champs dont certains sont potentiellement nuls.

Le problème est que si l'un de ces champs est nul, la colonne calculée entière sera nulle. Je comprends de la documentation Microsoft que cela est attendu et peut être désactivé via le paramètre SET CONCAT_NULL_YIELDS_NULL. Cependant, là, je ne veux pas changer ce comportement par défaut car je ne connais pas ses implications sur d'autres parties de SQL Server.

Existe-t-il un moyen pour moi de simplement vérifier si une colonne est nulle et d'ajouter uniquement son contenu dans la formule de colonne calculée si ce n'est pas nul?

Alex
la source
2
La réponse acceptée était juste au moment où la question a été posée, mais pour tout le monde sur SQL Server 2012 et versions ultérieures (et cette étape qui devrait être tout le monde) @ Martin-Smiths est la meilleure car elle gère automatiquement les valeurs nulles.
Dowlers

Réponses:

142

Vous pouvez utiliser ISNULL(....)

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

Si la valeur de la colonne / expression est effectivement NULL, alors la deuxième valeur spécifiée (ici: chaîne vide) sera utilisée à la place.

marc_s
la source
22
"Coalesce" est le nom de la fonction standard ANSI, mais ISNULL est plus facile à épeler.
Philip Kelley
1
Et ISNULL semble également être un peu plus rapide sur SQL Server - donc si vous souhaitez l'utiliser dans une fonction qui concatène des chaînes dans une colonne calculée, vous pouvez renoncer à la norme ANSI et opter pour la vitesse (voir Adam Machanic: sqlblog.com / blogs / adam_machanic / archive / 2006/07/12 /… )
marc_s
Je viens d'utiliser cette requête Isnull (,), cela a beaucoup changé car je concaténais des valeurs ensemble et si l'une d'entre elles était nulle, tout devenait également nul.
Sizons
L'utilisation ISNULL()est une bonne solution mais à partir de SQL Server 2012, vous pouvez également utiliser la CONCATfonction pour obtenir le même résultat:CONCAT(@Column1, @Column2)
Muhammad Musavi
2
Il convient de noter ici que si vous souhaitez échanger nullcontre autre chose qu'une chaîne vide, c'est-à-dire IsNull(@Column1, 'NULLVALUE')que IsNullla longueur de la chaîne de remplacement est limitée à la longueur de la colonne qu'elle remplace, alors que ce n'est pas le cas avecCoalesce
Jamie
58

À partir de SQL Server 2012, tout cela est beaucoup plus facile avec la CONCATfonction.

Il traite NULLcomme une chaîne vide

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


SELECT CONCAT(@Column1,@Column2,@Column3); /*Returns FooBar*/
Martin Smith
la source
Merci! C'était ce dont j'avais besoin !!
Shiva
Pour les versions plus anciennes, vous obtenez "'CONCAT' n'est pas un nom de fonction intégré reconnu", alors utilisez COALESCE
Savage
3
@Savage - COALESCE ne fonctionnera pas car il ne concatène pas, il renvoie juste le premier argument non nul
codeulike
30

Utilisez COALESCE . Au lieu de l' your_columnutiliser COALESCE(your_column, ''). Cela renverra la chaîne vide au lieu de NULL.

Mark Byers
la source
OP veut concaténer des chaînes ensemble, COALESCE ne le fera pas
codeulike
12

Utilisation

SET CONCAT_NULL_YIELDS_NULL  OFF 

et la concaténation de valeurs nulles à une chaîne n'entraînera pas nul.

Veuillez noter qu'il s'agit d'une option obsolète, évitez d'utiliser. Consultez la documentation pour plus de détails.

Simran
la source
11

Vous pouvez également utiliser CASE - mon code ci-dessous vérifie à la fois les valeurs nulles et les chaînes vides, et ajoute un séparateur uniquement s'il y a une valeur à suivre:

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 
Eddie
la source
8

Je voulais juste contribuer à cela si quelqu'un cherchait de l'aide pour ajouter des séparateurs entre les chaînes, selon qu'un champ est NULL ou non.

Donc, dans l'exemple de création d'une adresse sur une ligne à partir de champs séparés

Adresse1 , Adresse2 , Address3 , Ville , PostCode

dans mon cas, j'ai la colonne calculée suivante qui semble fonctionner comme je le souhaite:

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

J'espère que cela aide quelqu'un!

ebooyens
la source
Il y a un peu de bracketing imbriqué redondant qui pourrait être supprimé. Une autre astuce est que vous pouvez également supprimer l'instruction case comme si address1 est nul, l'expression entière sera évaluée à null (bien que l'instruction case attire l'attention sur le fait que cela peut arriver)
Alternator
7

ISNULL(ColumnName, '')

Ian Jacobs
la source
1

J'ai eu beaucoup de problèmes avec ça aussi. Impossible de le faire fonctionner en utilisant les exemples de cas ci-dessus, mais cela fait le travail pour moi:

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

Replace corrige les doubles espaces causés par la concaténation d'espaces simples sans rien entre eux. r / ltrim supprime tous les espaces aux extrémités.

BryDav
la source
0

Dans Sql Server:

insert into Table_Name(PersonName,PersonEmail) values(NULL,'[email protected]')

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

Code derrière:

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

insert into Table_Name(PersonName,PersonEmail) values(name,'"+email+"')
Srinivasula Reddy
la source
0

Cet exemple vous aidera à gérer différents types lors de la création d'instructions d'insertion

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'
Akmal Salikhov
la source