========================
2014年2月28日追記
後述のリンク先にてここで書かれていることより
大きな違いについて言及されているので
一読を勧める。
========================

MS SQL Server に於いて

    SELECT ISNULL(a,0) FROM test1



    SELECT COALESCE(a,0) FROM test1

は同じ意味だと思っていた。

・・・しかし、上記の列a が nvarchar等文字列型だった場合は挙動が違ってくるのである。

 仕事で、うっかり文字列型の列に対して「ISNULL(a,0)」と
してしまっていたところがあった(犯人は僕)。
これは「汚いが動いてしまう」コードだった。
別の人が「ISNULL より DB2 でも使える COALESCE の方がいい」
と「COALESCE(a,0)」に変えてしまった。
すると、これは「通常動かない」コードになった。

・・・気づかずにWebサイトにリリースされて発覚し、
大急ぎで正しく「COALESCE(a,’’)」修正され、再リリースとなった。

「ISNULL(a,0)」の場合、型は「第一引数の型」となる。
したがって、a が null の場合でも暗黙のキャストで文字列型で返ってくる。
「COALESCE(a,0)」の場合、型は「最も優先度の高い型」となる。
文字列型よりも 数値型の方が優先度が高いのでこの列は 数値型になる。
そして、a に 数値型にキャストできない文字列が入っていれば
その時点で SQL がエラーになる。

うぅ、ごめんなさい。。。。。orz

・・・ってもうちょっと調べた。
列a の文字列が全て数値にキャストできる場合、SQL の結果はきちんと返ってくる。
その場合、「ISNULL(a,0)」と「COALESCE(a,0)」は見かけは同じ結果が返ってくる。
しかし、「ISNULL(a,0)」は文字列型で、「COALESCE(a,0)」は数値型である。
そういうわけで、次の C# のプログラムの場合、ISNULL だと動くが COALESCE にすると実行時エラーになる。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;

namespace CoalesceTest
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable("test");
//dt.Columns.Add(new DataColumn("NewA",typeof(string)));
SqlConnectionStringBuilder scb = new SqlConnectionStringBuilder();
scb.DataSource = ".";
scb.InitialCatalog = "test";
scb.IntegratedSecurity = true;

SqlConnection cnn = new SqlConnection(scb.ConnectionString);
SqlDataAdapter da = new SqlDataAdapter("SELECT ISNULL(a,0) NewA FROM test1", cnn);
//SqlDataAdapter da = new SqlDataAdapter("SELECT COALESCE(a,0) NewA FROM test1", cnn);
da.TableMappings.Add("table", "test");
da.Fill(dt);
foreach (DataRow row in dt.Rows)
{
string str = (string)row["NewA"]; <=== COALESCE だとエラー
Debug.WriteLine(str);
}
}
}
}


まぁ、型には注意しましょう。あうあうあう。
===
2011年2月15日追記
SQL Server のデータ型の優先順位(SQL Server 2008)
http://msdn.microsoft.com/ja-jp/library/ms190309.aspx

=====
2014年2月28日
ISNULL と Coalesce にはもっと重大な違いがあった。
一読されることを勧める。
http://sqlmag.com/t-sql/coalesce-vs-isnull

コメント