J'ai écrit une déclaration T-SQL similaire à celle-ci (l'original a l'air différent mais je veux donner un exemple simple ici):
SELECT first_name +
CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name
FROM dbo.person
Cette instruction ne contient aucune erreur de syntaxe, mais la clause case choisit toujours la partie ELSE - également si le nom de famille est nul. Mais pourquoi?
Ce que je veux faire, c'est unir le prénom et le nom de famille, mais si le nom de famille est nul, le nom entier devient nul:
SELECT first_name +
CASE last_name WHEN null THEN '' ELSE ' ' + last_name END AS Name
FROM dbo.person
Savez-vous où est le problème?
COALESCE
se traduit essentiellement en interneCASE
. Le problème avec CASE est qu'illast_name
est évalué deux fois et qu'il peut entraîner d'autres effets secondaires - voir cet excellent article . Pour résoudre ce qui a été demandé, je préfère aller avecISNULL(' '+ last_name, '')
mentionné dans le commentaire ci-dessous.La partie WHEN est comparée à ==, mais vous ne pouvez pas vraiment comparer avec NULL. Essayer
à la place ou COALESCE:
('' + last_name est NULL lorsque last_name est NULL, donc il devrait retourner '' dans ce cas)
la source
Il existe de nombreuses solutions, mais aucune ne explique pourquoi la déclaration d'origine ne fonctionne pas.
Après le moment, il y a une vérification de l'égalité, qui doit être vraie ou fausse.
Si une ou les deux parties d'une comparaison sont nulles, le résultat de la comparaison sera INCONNU, qui est traité comme faux dans une structure de cas. Voir: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
Pour éviter cela, Coalesce est le meilleur moyen.
la source
Compte tenu de votre requête, vous pouvez également le faire:
la source
ISNULL(' '+ last_name, '')
pour éviter l'espace redondant.Le problème est que null n'est pas considéré comme égal à lui-même, donc la clause ne correspond jamais.
Vous devez vérifier explicitement null:
la source
essayer:
Cela ajoute l'espace au nom de famille, s'il est nul, l'espace + le nom entier va à NULL et vous obtenez seulement un prénom, sinon vous obtenez un premier + espace + nom.
cela fonctionnera tant que le paramètre par défaut pour la concaténation avec des chaînes nulles est défini:
cela ne devrait pas être un problème car le
OFF
mode disparaîtra dans les futures versions de SQl Serverla source
Le problème est que NULL n'est pas considéré comme égal à rien, même pas à lui-même, mais la partie étrange est qu'il n'est pas non plus égal à lui-même.
Considérez les instructions suivantes (ce qui est illégal en BTW dans SQL Server T-SQL mais valide dans My-SQL, mais c'est ce que ANSI définit pour null, et peut être vérifié même dans SQL Server en utilisant des instructions case, etc.)
SELECT NULL = NULL -- Results in NULL
SELECT NULL <> NULL -- Results in NULL
Il n'y a donc pas de réponse vraie / fausse à la question, mais la réponse est également nulle.
Cela a de nombreuses implications, par exemple dans
WHEN NULL
condition )SELECT a + NULL -- Results in NULL
On peut remplacer ce comportement dans SQL Server en spécifiant
SET ANSI_NULLS OFF
, mais ce n'est PAS recommandé et ne doit pas être fait car cela peut provoquer de nombreux problèmes, simplement en raison de la déviation de la norme.(En remarque, dans My-SQL, il existe une option pour utiliser un opérateur spécial
<=>
pour la comparaison nulle.)En comparaison, dans les langages de programmation généraux, null est traité est une valeur régulière et est égal à lui-même, cependant c'est la valeur NAN qui n'est pas non plus égale à elle-même, mais au moins elle retourne 'false' lors de la comparaison avec elle-même, (et lors de la vérification de non égal à différents langages de programmation ont différentes implémentations).
Notez cependant que dans les langages de base (c'est-à-dire VB, etc.), il n'y a pas de mot-clé "null" et à la place, on utilise le mot-clé "Nothing", qui ne peut pas être utilisé en comparaison directe et à la place, il faut utiliser "IS" comme dans SQL, cependant, il est en fait égal à lui-même (lors de l'utilisation de comparaisons indirectes).
la source
la source
Lorsque vous êtes frustré d'essayer ceci:
Essayez plutôt celui-ci:
LEN(ISNULL(last_Name,''))
mesure le nombre de caractères dans cette colonne, qui sera zéro, qu'elle soit vide ou NULL,WHEN 0 THEN
sera donc évalué à vrai et retournera le '' comme prévu.J'espère que c'est une alternative utile.
J'ai inclus ce cas de test pour SQL Server 2008 et supérieur:
la source
Jason a détecté une erreur, donc cela fonctionne ...
Quelqu'un peut-il confirmer les autres versions de la plate-forme?
Serveur SQL:
MySQL:
Oracle:
la source
Vous pouvez utiliser la fonction IsNull
si une colonne est nulle, vous obtiendrez un caractère vide
Compatible avec Microsoft SQL Server 2008+
la source
Utilisez la fonction CONCAT disponible dans SQL Server 2012.
la source
J'ai essayé de lancer une chaîne et de tester une chaîne de longueur nulle et cela a fonctionné.
la source
NULL ne vaut rien. L'instruction case dit essentiellement que lorsque la valeur = NULL .. elle ne frappera jamais.
Il existe également plusieurs procédures stockées système qui ne sont pas écrites correctement avec votre syntaxe. Voir sp_addpullsubscription_agent et sp_who2.
J'aimerais savoir comment informer Microsoft de ces erreurs car je ne suis pas en mesure de modifier les procs stockés du système.
la source