web-dev-qa-db-fra.com

Utiliser ISNULL vs utiliser COALESCE pour vérifier une condition spécifique?

Je sais que plusieurs paramètres peuvent être passés à COALESCE, mais lorsque vous voulez vérifier une seule expression pour voir si elle n'existe pas, utilisez-vous une valeur par défaut ou est-ce une meilleure pratique d'utiliser ISNULL à la place?

Y a-t-il un gain de performances entre les deux?

69
JBone

Ce problème signalé sur Microsoft Connect révèle quelques différences entre COALESCE et ISNULL:

une première partie de notre traitement réécrit COALESCE( expression1, expression2 ) en CASE WHEN expression1 IS NOT NULL THEN expression1 ELSE expression2 END. Dans [cet exemple]:

COALESCE ( ( SELECT Nullable
             FROM Demo
             WHERE SomeCol = 1 ), 1 )

nous générons:

SELECT CASE
          WHEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) IS NOT NULL
          THEN (SELECT Nullable FROM Demo WHERE SomeCol = 1)
          ELSE 1
       END

Les étapes ultérieures du traitement des requêtes ne comprennent pas que les deux sous-requêtes étaient à l'origine la même expression, elles exécutent donc la sous-requête deux fois ...

Une solution de contournement, bien que je déteste le suggérer, consiste à remplacer COALESCE par ISNULL, car ce dernier ne fait pas double emploi avec la sous-requête.

55
onedaywhen

Je ne pense pas, mais COALESCE est dans la norme SQL '92 et supporté par des bases de données plus différentes. Si vous optez pour la portabilité, n'utilisez pas ISNULL.

24
GolezTrol

Dans COALESCE vous pouvez avoir plusieurs expressions, comme dans ISNULL vous ne pouvez vérifier que une expression

COALESCE ( expression [ ,...n ] ) 

ISNULL ( check_expression , replacement_value )
11
otti

Il convient de mentionner que la gestion des types entre les deux peut également faire une différence (voir cet élément de réponse connexe (2) ).

Supposons qu'une requête tente d'utiliser un raccourci pour écrire une comparaison nulle:

select * from SomeTable
 where IsNull(SomeNullableBitField, -1) != IsNull(SomeOtherNullableBitField, -1);

qui est différent de

select * from SomeTable
 where coalesce(SomeNullableBitField, -1) != coalesce(SomeOtherNullableBitField, -1);

Parce que dans le premier cas, IsNull () force le type à être un peu (donc -1 est converti en vrai) tandis que le second cas promouvra les deux en int.

with input as 
(
  select convert(bit, 1) as BitOn,      
         convert(bit, 0) as BitOff,
         convert(bit, null) as BitNull
)
select BitOn, 
       BitOff,
       BitNull,
       IsNull(BitOn, -1) IsNullBitOn,         -- true
       IsNull(BitOff, -1) IsNullBitOff,       -- false
       IsNull(BitNull, -1) IsNullBitNull,     -- true, converts the -1 to bit
       coalesce(BitOn, -1) CoalesceBitOn,     -- 1
       coalesce(BitOff, -1) CoalesceBitOff,   -- 0       
       coalesce(BitNull, -1) CoalesceBitNull  -- -1
  from input;

Il existe un commentaire/lien similaire (@Martin Smith) sur la question elle-même.

7
crokusek

Une chose importante que je ne vois pas explicitement indiquée est que le type de sortie de ISNULL est similaire à la première expression mais avec COALESCE il retourne le type de données de la valeur de la plus haute priorité.

DECLARE @X VARCHAR(3) = NULL
DECLARE @Y VARCHAR(10) = '123456789'
/* The datatype returned is similar to X, or the first expression*/
SELECT ISNULL(@X, @Y) ---> Output is '123'
/* The datatype returned is similar to Y, or to the value of highest precedence*/
SELECT COALESCE(@X, @Y) ---> Output is '123456789'
5
BICube

Cette explication donne clairement sur coalesce vs isnull

La fonction COALESCE dans SQL renvoie la première expression non NULL parmi ses arguments. La syntaxe de COALESCE est la suivante:

 COALESCE ("expression 1", "expressions 2", ...)

C'est la même chose que l'instruction CASE suivante:

SELECT CASE ("column_name")
  WHEN "expression 1 is not NULL" THEN "expression 1"
  WHEN "expression 2 is not NULL" THEN "expression 2"
  ...
  [ELSE "NULL"]
  END
FROM "table_name";

Dans SQL Server, la fonction ISNULL () est utilisée pour remplacer la valeur NULL par une autre valeur.

select CountryName = ISNULL("columnname", 'INDIA') from Countries

Coalesce renvoie la première expression non nulle où as isull () est utilisé pour remplacer la valeur nulle par notre valeur souhaitée.

COALESCE fait partie des normes ANSI et est disponible dans presque toutes les bases de données.

lors du choix entre ISNULL v COALESCE, les paramètres doivent être pris en compte:

  1. COALESCE détermine le type de la sortie en fonction de la priorité du type de données où, comme avec ISNULL, le type de données n'est pas influencé par la priorité du type de données.
  2. Envisagez de suivre les instructions SQL

    DECLARE @c5 VARCHAR(5);
    SELECT 'COALESCE', COALESCE(@c5, 'longer name')
    UNION ALL
    SELECT 'ISNULL',   ISNULL(@c5,   'longer name');
    

Résultats:

COALESCE longer name
ISNULL   longe

Cela se produit car ISNULL prend le type de données du premier argument, tandis que COALESCE inspecte tous les éléments et choisit le meilleur ajustement (dans ce cas, VARCHAR (11))

Pour une explication plus détaillée sur la décision entre COALESCE vs ISNULL, vérifiez ceci: https://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/

2

Lorsqu'il n'y a qu'une seule condition nulle, ISNULL aura moins de surcharge. Cependant, la différence est probablement négligeable.

2
James Johnson

NULL et COALESCE ne sont pas toujours interchangeables. Il mérite de connaître leurs différences afin de savoir quand il vaut mieux utiliser l'un sur l'autre:

enter image description here

Le tableau ci-dessus est une comparaison entre ISNULL et COALESCE du livre Exam Ref 70-761 Querying Data with Transact-SQL Écrit par Itzik Ben-Gan.


  1. Nombre de paramètres pris en charge - 2 Pour ISNULL vs >2 Lors de l'utilisation de COALESCE
  2. ISNULL est une fonctionnalité T-SQL propriétaire et COALESCE est la norme SQL ISO/ANSI
  3. Le type de données du résultat est important. Après avoir lu les notes du tableau ci-dessus, vérifiez les cas suivants:

    DECLARE @x VARCHAR(3)  = NULL
           ,@y VARCHAR(10) = '1234567890';
    
    SELECT ISNULL(@x, @y) AS [ISNULL], COALESCE(@x, @y) AS [COALESCE];
    

    enter image description here

    ISNULL obtient le type de données du premier argument car c'est le littéral non NULL. Il s'agit de VARCHAR(3) et est un résultat, les données du deuxième argument sont coupées pour y correspondre. Avec COALESCE le type de données si la priorité la plus élevée est utilisée.

    DECLARE @x VARCHAR(8)  = '123x5'
           ,@y INT = 123;
    
    SELECT ISNULL(@x, @y) AS [ISNULL];
    SELECT COALESCE(@x, @y) AS [COALESCE];
    

    enter image description here

    enter image description here

    ISNULL renvoie le type de données du premier argument, tandis que dans COALESCE, nous obtenons une erreur, car INT a la priorité la plus élevée et la conversion de la première valeur d'argument en INT échoue.

  4. La nullité du résultat peut également être importante. Par exemple:

    DECLARE @x VARCHAR(3) = NULL
           ,@y VARCHAR(3) = NULL;
    
    DROP TABLE IF EXISTS [dbo].[DataSource01];
    
    SELECT ISNULL(10, 20) AS [C1]
          ,ISNULL(@x, 'text') AS [C2]
          ,ISNULL(@x, @y) AS [C3]
    INTO [dbo].[DataSource01];
    
    DROP TABLE IF EXISTS [dbo].[DataSource02];
    
    SELECT COALESCE(10, 20) AS [C1]
          ,COALESCE(@x, 'text') AS [C2]
          ,COALESCE(@x, @y) AS [C3]
    INTO [dbo].[DataSource02];
    

    Vérifions la propriété Nullable de chaque colonne:

    enter image description here

    enter image description here

    En utilisant COALESCE, nous avons une propriété NOT NULL De colonne définie sur Yes, uniquement lorsque toutes les entrées ne sont pas nulles.

  5. Selon le standard SQL, l'expression COALESCE est traduite en:

    CASE WHEN (<subquery>) IS NOT NULL THEN (<subquery>) ELSE 0 END
    

    Si le résultat de l'exécution de la sous-requête dans la clause WHEN n'est pas NULL, SQL Server l'exécute une deuxième fois dans la clause THEN. En d'autres termes, dans un tel cas, il l'exécute deux fois. Ce n'est que si le résultat de l'exécution dans la clause WHEN est NULL que SQL Server n'exécute plus la sous-requête, mais renvoie plutôt l'expression ELSE. Ainsi, lorsque vous utilisez des sous-requêtes, la fonction ISNULL présente un avantage en termes de performances.

1
gotqn