列をtrueまたはfalseのみにするビューを作成しようとしています。しかし、私が何をしようとも、SQL Server(2008)は私のビット列が何らかの形でヌルになる可能性があると考えています。
「製品」という名前のテーブルがあり、「ステータス」列は_INT, NULL
_です。ビューでは、Productの各行に対して行を返します。Product.Status列が3に等しい場合はBIT列をtrueに設定し、そうでない場合はビットフィールドをfalseに設定します。
SQLの例
_SELECT CAST( CASE ISNULL(Status, 0)
WHEN 3 THEN 1
ELSE 0
END AS bit) AS HasStatus
FROM dbo.Product
_
このクエリをビューとして保存し、オブジェクトエクスプローラーで列を見ると、列HasStatusは_BIT, NULL
_に設定されています。ただし、決してNULLであってはなりません。この列を_NOT NULL
_にするために使用できる魔法のSQLトリックはありますか。
CASE
の周りのCAST()
を削除すると、列は_NOT NULL
_として正しく設定されますが、列のタイプはINT
に設定されます。私が欲しいものではありません。 BIT
にしたいです。 :-)
クエリを少し並べ替えることで、目的を達成できます。トリックは、結果の値がISNULL
にならないことをSQL Serverが理解する前に、NULL
が外側にある必要があることです。
SELECT ISNULL(CAST(
CASE Status
WHEN 3 THEN 1
ELSE 0
END AS bit), 0) AS HasStatus
FROM dbo.Product
私が実際にこれが便利だと思う理由の1つは、 [〜#〜] orm [〜#〜] を使用し、結果の値をマップしたくない場合です。 null許容型。アプリケーションが値をnullにしない可能性があると見なすと、すべてのことが簡単になります。その後、null例外などを処理するコードを記述する必要はありません。
参考までに、このメッセージに出くわした人のために、キャスト/変換の外側にISNULL()を追加すると、ビューのオプティマイザーが混乱する可能性があります。
インデックスキーと同じ値を使用しますが、数値精度の異なるタイプ(悪いことはわかっています)を使用した2つのテーブルがあり、最終結果を生成するためにビューを結合していました。しかし、ミドルウェアコードは特定のデータ型を探していたため、ビューには返される列の周りにCONVERT()がありました
OPが行ったように、ビューの結果の列記述子がNULL可能と定義していることに気づき、2つのテーブルの主キー/外部キーだと考えていました。なぜ結果をnull可能として定義したいのですか?
私はこの投稿を見つけ、ISNULL()を列と出来事の周りに投げました-もうnullableではありません。
問題は、その列でクエリがフィルター処理されたときに、ビューのパフォーマンスがトイレをまっすぐに下がったことでした。
何らかの理由で、ビューの結果列の明示的なCONVERT()はオプティマイザーを台無しにしませんでした(精度が異なるためとにかくそれを行う必要がありました)が、大きなISNULL()ラッパーを追加しました方法。