2011-09-13 2 views
62

Je sais que plusieurs paramètres peuvent être passés à COALESCE, mais quand vous voulez vérifier une seule expression pour voir si elle n'existe pas, utilisez-vous un défaut ou est-il préférable d'utiliser ISNULL à la place?Utiliser ISNULL ou utiliser COALESCE pour vérifier une condition spécifique?

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

+5

La [documentation COALESCE] (http://msdn.microsoft.com/fr-fr/library/ms190349.aspx) a cette remarque: ISNULL et COALESCE bien qu'équivalents, peuvent se comporter différemment. Une expression impliquant ISNULL avec des paramètres non NULL est considérée comme NOT NULL, tandis que les expressions impliquant COALESCE avec des paramètres non NULL sont considérées comme étant NULL ... –

+3

'ISNULL' va aussi contraindre le résultat au type de données de la première expression [ comme illustré ici] (http://haacked.com/archive/2005/01/21/difference-between-isnull-and-coalesce.aspx) –

+4

Cet article explique assez bien les différences ... http: // sqlmag .com/t-sql/coalesce-vs-isnull –

Répondre

47

This problem reported on Microsoft Connect révèle quelques différences entre COALESCE et ISNULL:

une première partie de notre traitement récrit COALESCE(expression1, expression2) comme 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 

étapes ultérieures de traitement des requêtes ne comprennent pas que les deux sous-requêtes étaient à l'origine la même expression, de sorte qu'ils exécutons la sous-requête deux fois ..

Une solution de contournement, bien que je déteste suggérer, est de changer COALESCE à ISNULL, puisque ce dernier ne duplique pas la sous-requête.

+2

question rapide, si vous avez 3 valeurs, comme coalesce (expression1, expression2, expression3, 1), où ces 'expressions' sont en fait des instructions select, cela aurait-il du sens pour les instructions isnull imbriquées? ie isnull (expression1, isnull (expression2, isnull (expression3, 1))) – ganders

22

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

+2

est-il isnull de ifnull? –

+9

Mon point exactement. ;-D Et c'est NVL dans Oracle. – GolezTrol

1

Lorsqu'il n'y a qu'une seule condition nulle, ISNULL aura moins de temps système. La différence est probablement négligeable, cependant.

+1

Avez-vous des arguments à l'appui de l'affirmation selon laquelle il y a moins de frais généraux avec 'ISNULL'? –

+0

@JoshuaDrake: Il y a deux zones où 'COALESCE' introduirait plus de surdébit lorsqu'il est utilisé de façon interchangeable. Premièrement, 'ISNULL' traite un nombre fixe d'entrées, où' COALESCE' est désigné pour fonctionner avec n'importe quel nombre d'entrées. Deuxièmement, 'COALESCE' est configuré pour renvoyer le type de données de l'expression ayant la plus haute priorité de type de données, alors que' ISNULL' renvoie le même type que 'check_expression'. Comme je l'ai dit plus haut, dans les versions ultérieures de SQL Server, la différence est probablement négligeable, mais à proprement parler, il y a toujours un surcoût. –

9

En COALESCE vous pouvez avoir plusieurs expressions, où, comme dans ISNULL vous pouvez vérifier qu'une seule expression

COALESCE (expression [ ,...n ]) 

ISNULL (check_expression , replacement_value) 
-2

En COALESCE on peut utiliser plusieurs expressions, il renvoie la valeur qui n'est pas nulle et se produit d'abord ... par exemple

DECLARE @Value1 INT, @Value2 INT, @Value3 INT, @Value4 INT 
SELECT @Value2 = 2, @Value4 = 4 
SELECT COALESCE(@Value1, @Value2, @Value3, @Value4) 
SELECT COALESCE(@Value1, @Value4, @Value3, @Value2) 

et si l'expression ISNULL nulle elle retourne deuxième paramètre fourni, et bien sûr vous pouvez vérifier que pour un expression ...

Donc, si vous voulez vérifier expression multiple et sélectionnez d'abord non nul d'entre eux, puis utilisez Coalesce autrement aller pour ISNULL

+2

OP a déclaré qu'ils étaient conscients de la capacité de COALESCE à gérer plusieurs paramètres, la question concerne le cas spécifique lorsqu'il n'y en a que deux. –

+0

@JoshuaDrake s'il vous plaît lire la réponse complète ... J'ai lu la question et je vous demande de lire ma réponse complètement ... Il est très facile de regarder un certain point et le voter –

4

Il convient de mentionner que le traitement de type entre les deux peut aussi faire une différence (voir this related answer item (2)).

Dis une requête essaie d'utiliser un raccourci pour l'écriture de comparaison de valeur nulle:

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

qui est différente de celle de

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

Comme dans le premier cas, les forces IsNull() du type à un bit (donc -1 est converti en vrai) alors que le second cas va promouvoir à la fois un 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.

4

Une chose importante que je ne vois pas explicitement indiqué est que le type de sortie de ISNULL est similaire à la première expression mais avec COALESCE il renvoie le type de données 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' 
+3

Ce n'est pas une question de première ou seconde expression. Voir [ici] (http://stackoverflow.com/questions/18828641/sql-difference-between-coalesce-and-isnull/18828687#18828687): 'ISNULL utilise le type de données du premier paramètre, COALESCE suit l'expression CASE règle et retourne le type de données avec la plus haute priorité. –

2

Cette explication donne clairement soudent 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", ...) 

Il est le même 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 avec une autre valeur . Coalesce retourne la première expression non nulle où isnull() est utilisé pour remplacer la valeur nulle par notre valeur désirée.

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

au moment de décider entre ISNULL v COALESCE-t-il des paramètres doit être pris en charge au large:

  1. COALESCE détermine le type de sortie en fonction de la priorité du type de données où comme avec ISNULL, le type de données ne sont pas influencés par les données tapez la priorité.
  2. Consider suivant 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 parce que ISNULL prend le type du premier argument de données, alors que COALESCE inspecte tous les éléments et choisit la meilleur ajustement (dans ce cas, VARCHAR (11))

Pour des explications plus détaillées sur decidin g entre COALESCE vs ISNULL vérifier: https://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/

0

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

enter image description here

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


  1. Nombre de paramètres pris en charge - 2 pour ISNULL vs >2 lors de l'utilisation COALESCE
  2. ISNULL est fonction T-SQL exclusive et COALESCE est la norme ISO/ANSI SQL
  3. Le type du résultat de données est important. Après avoir lu les notes dans le 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

    Le ISNULL est d'obtenir le type du premier argument de données est la non NULL littérale. Il est VARCHAR(3) et est un résultat, le deuxième argument de données est coupé pour le faire correspondre. Avec COALESCE le type de données si la plus haute priorité est utilisé.

    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

    Le ISNULL renvoie le type de premier argument de données, alors que dans COALESCE nous obtenons une erreur, car le INT a priorité la plus élevée et la de conversion le premier valeur d'argument à INT échoue.

  4. La nullité du résultat peut également être importante. Pour, 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 la colonne mis à Yes, seulement quand toutes les entrées sont non nulles.

  5. Selon la norme SQL, l'expression COALESCE est traduit à:

    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. Uniquement si le résultat de l'exécution dans la clause WHEN est NULL, SQL Server ne exécuter à nouveau la sous-requête, retourne plutôt l'expression ELSE. Donc lors de l'utilisation de sous-requêtes, la fonction ISNULL a un avantage de performance .

Questions connexes