SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

SQL ServerでNull値に対処する

Null値を適切に処理するための一貫した方法とは

  • X ポスト
  • このエントリーをはてなブックマークに追加

問題が起きる前にNullを見つける

 Nullが出現する式では、不良なデータが返される可能性があります。例えば、図1はNullをNullと照合した結果を示しています。ANSI_NULLSの設定によっては、このステートメントは何もレコードを返さないことがあります。

図1 NullとNullの照合の結果: ANSI規格に従うと、Nullを含む照合では常にNullが返される
図1 NullとNullの照合の結果: ANSI規格に従うと、Nullを含む照合では常にNullが返される

 ANSI_NULLSオプションは、デフォルトではオフ(False)になっています。つまり、NullとNullの照合ではNullの代わりにTrueが返されます。このオプションをオン(True)にすると、NullとNullの照合では常にNullが返されます。デフォルトの設定はANSI規格に違反していますが、そうすることでエラーの発生を防いでいます。このオプションをどのように設定するかは好みの問題ですが、それによってNullの評価がどのように左右されるかを知っておくことは重要です。

 どのような問題が起きる可能性があるかが分かるように、次のステートメントではオプションをオンにしています。

USE AdventureWorks
SET ANSI_NULLS ON
SELECT EmployeeID 
FROM HumanResources.Employee
WHERE ManagerID = NULL

 レコードを調べると、ManagerID列にNull値を含むレコードが1つあることが分かります。ところが、前のステートメントを実行すると空の結果セットが返されます。つまり、存在しているレコードが返されません。さらに悪いことに、通常のエラーではなく、空の結果セットで体現される「エラー」は見逃される可能性が高いと考えられます。

 このオプションの設定にかかわらず、Null値を検索する適切な方法は、次のようにIS NULLを使うことです。

USE AdventureWorks
SELECT EmployeeID 
FROM HumanResources.Employee
WHERE ManagerID IS NULL

 図2を見ると分かるように、ANSI_NULLSオプションの設定を意識する必要はありません。しかも、このオプションがだれかにリセットされても、ステートメントは常に正しく機能します。

図2 IS NULLでNull値を検索: ANSI_NULLSの設定にかかわらず、IS NULLではNull値が検出される
図2 IS NULLでNull値を検索: ANSI_NULLSの設定にかかわらず、IS NULLではNull値が検出される

 IS NULLを使うと、特定の列のNull値を簡単に検索できますが、複数の列や全部の列を検索するのは少し複雑です。当初は、たくさんのOR句を使った複雑なステートメントを検討するかもしれませんが、その必要はありません。単に次のような構文を使ってフィールドを連結するだけで済みます。

SELECT list|* 
FROM table
WHERE nulcol1 + nulcol2 + ... IS NULL

 複数の列を組み合わせることも、全部の列を連結することもできます。3つのフィールドを連結した結果を図3に示します。

USE AdventureWorks
SELECT * 
FROM Person.Contact
WHERE Suffix + EmailAddress + Phone IS NULL
図3 3つのフィールドを連結した結果: 複数の列を組み合わせることも、全部の列を連結することもできる
図3 3つのフィールドを連結した結果: 複数の列を組み合わせることも、全部の列を連結することもできる

 チェックする各列を明示的に参照する必要はあるものの、この方法を使うと入力の手間を多少減らすことができます。Null許容型でない列は連結しないでください。エラーが発生します。この方法は、Null許容型のフィールドでのみ有効です。

 この連結の動作は便利ですが、予期しない結果が返されることもあります。例えば、次のステートメントでは名、姓、およびミドルネームを連結しています。

Use AdventureWorks
SELECT FirstName + ' ' + MiddleName + ' ' + LastName
FROM Person.Contact
図4 ANSI_NULLSの設定は無関係:連結によってNull値が返されることがある
図4 ANSI_NULLSの設定は無関係:連結によってNull値が返されることがある

 図4には思いがけない結果が表示されています。この場合、ANSI_NULLSの設定は無関係です。いずれかの名前の値がNullの場合、結果の値はNullになります。この問題は次のようにISNULL()を使って回避できます(図5を参照)。

Use AdventureWorks
SELECT FirstName + ' ' + ISNULL(MiddleName, '') + LastName
FROM Person.Contact
図5 ISNULL()でNullを検出:ISNULL()を使ってNull値を検出する
図5 ISNULL()でNullを検出:ISNULL()を使ってNull値を検出する

 すべての列をISNULL()に入れる必要はありません。列のプロパティで値が必須になっている場合は、列がNullになる可能性はありません(FirstNameLastNameはNull許容型ではありません)。ISNULL()関数では、次の構文を使い、指定した代替値でNull値を置き換えます。checkexpressionはNull値かどうかをチェックする値または列、replacementvalueはNullの代わりに使用する値です。

ISNULL(checkexpression, replacementvalue)

 この例では、Null許容型の列はMiddleNameだけです。ミドルネームの値を含まないレコードでは、名と姓の間に2つのスペース文字が挿入されます。

 SQL ServerのCONCATENATE_NULL_YIELDS_NULLの設定は、Null値を連結するすべての式の結果に影響を与えます。デフォルトはオン(True)で、Nullを連結するとNullが返されます。オフ(False)にすると、SQL ServerはNullを無視し、Null以外の他の値を連結した結果を返します。前のIS NULLの例と同様に、ISNULL()を使うと、このオプションがだれかにリセットされても、予期しない結果を回避できます。

 たとえNull値による問題が起きなくても、ユーザーにとってNull値はほとんど意味を持ちません。より意味のあるデータの方がユーザーには役立ちます。データを参照するときに、ユーザーがNULLの意味を推測してくれるかもしれませんが、それを期待すべきではありません。次のステートメントのISNULL()関数では、図3や図4のようにNULLを表示する代わりに、図6に示すように「None」を表示しています。

USE AdventureWorks
SELECT Contact, ISNULL(Suffix, 'None') 
FROM Person.Contact
図6 ISNULL()関数で「None」を表示: Null値が出現した場合に、より意味のある情報をユーザーに表示する
図6 ISNULL()関数で「None」を表示: Null値が出現した場合に、より意味のある情報をユーザーに表示する

 こうすればユーザーに分かりやすくなります。

次のページ
集計でNullをどのように評価するか

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Susan Sales Harkins(Susan Sales Harkins)

 独立コンサルタントとして活動するかたわら、データベーステクノロジに関する記事や書籍を執筆。最近の著書は『Mastering Microsoft SQL Server 2005 Express』(Mike Gunderloyと共著、Sybex刊)。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4381 2009/09/21 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング