Discussione:
Differenza tra ISNULL e COALESCE
(troppo vecchio per rispondere)
giorgio rancati
2005-07-25 15:05:13 UTC
Permalink
Ciao a tutti,

pensavo che la funzione COALESCE con due parametri fosse equivalente a
ISNULL ma non è sempre così.

Provate Questo script
-----
Use TempDb
Go

Create Table Tab1
(Campo1 Varchar(5))

Insert Tab1 Values('A')
Insert Tab1 Values(' A')
Insert Tab1 Values(' A')
Insert Tab1 Values('B')
Insert Tab1 Values(' B')
Insert Tab1 Values(DEFAULT)
Insert Tab1 Values(DEFAULT)


SELECT LTRIM(ISNULL(Campo1, '')) AS A
FROM dbo.Tab1
GROUP BY LTRIM(ISNULL(Campo1, ''))
HAVING LTRIM(ISNULL(Campo1, '')) <> 'B'

SELECT LTRIM(COALESCE(Campo1, '')) AS A
FROM dbo.Tab1
GROUP BY LTRIM(COALESCE(Campo1, ''))
HAVING LTRIM(COALESCE(Campo1, '')) <> 'B'
----

la prima select funziona, la seconda da errore
-----
Server: messaggio 8121, livello 16, stato 1, riga 1
La colonna 'dbo.Tab1.Campo1' non è valida nella clausola HAVING perché non è
inclusa né in una funzione di aggregazione né nella clausola GROUP BY.
----

so bene che in questo caso posso spostare la Having nella Where
----
SELECT LTRIM(COALESCE(Campo1, '')) AS A
FROM dbo.Tab1
WHERE LTRIM(COALESCE(Campo1, '')) <> 'B'
GROUP BY LTRIM(COALESCE(Campo1, ''))
----

ma era solo una curiosità visto che anche Enterprise Manager compone lo
script con la Having e non con la Where.

Ciao
--
Giorgio Rancati
[Office Access MVP]
giorgio rancati
2005-07-25 15:22:40 UTC
Permalink
"giorgio rancati" <***@tiscali.it> ha scritto nel
messaggio news:***@TK2MSFTNGP15.phx.gbl...

umm....

In Sql Server 2005 9.0.1187 Preview di giugno funzionano bene tutte e due!

ho trovato un bacarozzo ?

:-)

Ciao
--
Giorgio Rancati
[Office Access MVP]
Andrea Montanari
2005-07-25 16:09:53 UTC
Permalink
salve Giorgio,
Post by giorgio rancati
Ciao a tutti,
pensavo che la funzione COALESCE con due parametri fosse equivalente a
ISNULL ma non è sempre così.
Provate Questo script
-----
Use TempDb
Go
Create Table Tab1
(Campo1 Varchar(5))
Insert Tab1 Values('A')
Insert Tab1 Values(' A')
Insert Tab1 Values(' A')
Insert Tab1 Values('B')
Insert Tab1 Values(' B')
Insert Tab1 Values(DEFAULT)
Insert Tab1 Values(DEFAULT)
SELECT LTRIM(ISNULL(Campo1, '')) AS A
FROM dbo.Tab1
GROUP BY LTRIM(ISNULL(Campo1, ''))
HAVING LTRIM(ISNULL(Campo1, '')) <> 'B'
SELECT LTRIM(COALESCE(Campo1, '')) AS A
FROM dbo.Tab1
GROUP BY LTRIM(COALESCE(Campo1, ''))
HAVING LTRIM(COALESCE(Campo1, '')) <> 'B'
----
la prima select funziona, la seconda da errore
-----
Server: messaggio 8121, livello 16, stato 1, riga 1
La colonna 'dbo.Tab1.Campo1' non è valida nella clausola HAVING
perché non è inclusa né in una funzione di aggregazione né nella
clausola GROUP BY. ----
so bene che in questo caso posso spostare la Having nella Where
----
SELECT LTRIM(COALESCE(Campo1, '')) AS A
FROM dbo.Tab1
WHERE LTRIM(COALESCE(Campo1, '')) <> 'B'
GROUP BY LTRIM(COALESCE(Campo1, ''))
----
ma era solo una curiosità visto che anche Enterprise Manager compone
lo script con la Having e non con la Where.
mi pare Luca, sul forum di Visual Basic Tip&Tricks abbia recentemente
affrontato un problema simile... solo che il sito ora e' down... c'era anche
indicato uno pseudo test di prestazione tra l'uso di COALESCE e ISNULL, dove
vince ISNULL, malgrado proprietario e non ANSI :D..
stavo guardando se per malaugurato caso i plans relativi fossero diversi, ma
si ferma prima il parser...

sviluppando pero' il COALESCE con la corrispettiva espressione CASE,
SELECT LTRIM(CASE WHEN Campo1 IS NULL THEN '' ELSE Campo1 END) AS A
FROM dbo.Tab1
GROUP BY LTRIM(CASE WHEN Campo1 IS NULL THEN '' ELSE Campo1 END)
HAVING LTRIM(CASE WHEN Campo1 IS NULL THEN '' ELSE Campo1 END) <> 'B'

torna a funzionare correttamente... come tutto funziona correttamente anche
su SQL Server 7.0 sp4..
mi sa che hai trovato un buco, sicuramente nel sp4 di SQL Server 2000... non
so se anche nei precedenti livelli di sp..
saluti
--
Andrea Montanari (Microsoft MVP - SQL Server)
http://www.asql.biz/DbaMgr.shtm http://italy.mvps.org
DbaMgr2k ver 0.14.0 - DbaMgr ver 0.59.0
(my vb6+sql-dmo little try to provide MS MSDE 1.0 and MSDE 2000 a visual
interface)
--------- remove DMO to reply
giorgio rancati
2005-07-25 16:38:08 UTC
Permalink
Post by Andrea Montanari
salve Giorgio,
mi pare Luca, sul forum di Visual Basic Tip&Tricks abbia recentemente
affrontato un problema simile... solo che il sito ora e' down... c'era anche
indicato uno pseudo test di prestazione tra l'uso di COALESCE e ISNULL, dove
vince ISNULL, malgrado proprietario e non ANSI :D..
stavo guardando se per malaugurato caso i plans relativi fossero diversi, ma
si ferma prima il parser...
si, confermo, il query plan di Sql 2005 traduce la COALESCE con
----
CASE WHEN Campo1 IS NULL ecc ecc
----
mentre non traduce ISNULL, lo tiene così come è.
Post by Andrea Montanari
torna a funzionare correttamente... come tutto funziona correttamente anche
su SQL Server 7.0 sp4..
mi sa che hai trovato un buco, sicuramente nel sp4 di SQL Server 2000... non
so se anche nei precedenti livelli di sp..
lo fa sia con la Sp4
----
Microsoft SQL Server 2000 - 8.00.2040 (Intel X86)
----
sia con la Sp3 + una patch sulla sicurezza
----
Microsoft SQL Server 2000 - 8.00.818 (Intel X86)
----
però visto che in Sql7 e in Sql2005 funziona, penso anche io che sia un
buco.
Nei casi in cui abbia bisogno di soli due parametri torno a riutilizzare
ISNULL.

Grazie della risposta :-)

Ciao
--
Giorgio Rancati
[Office Access MVP]
Loading...