web-dev-qa-db-ja.com

ビュー列をNOT NULLにする方法

列を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にしたいです。 :-)

74
René

クエリを少し並べ替えることで、目的を達成できます。トリックは、結果の値が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例外などを処理するコードを記述する必要はありません。

138
RedFilter

参考までに、このメッセージに出くわした人のために、キャスト/変換の外側にISNULL()を追加すると、ビューのオプティマイザーが混乱する可能性があります。

インデックスキーと同じ値を使用しますが、数値精度の異なるタイプ(悪いことはわかっています)を使用した2つのテーブルがあり、最終結果を生成するためにビューを結合していました。しかし、ミドルウェアコードは特定のデータ型を探していたため、ビューには返される列の周りにCONVERT()がありました

OPが行ったように、ビューの結果の列記述子がNULL可能と定義していることに気づき、2つのテーブルの主キー/外部キーだと考えていました。なぜ結果をnull可能として定義したいのですか?

私はこの投稿を見つけ、ISNULL()を列と出来事の周りに投げました-もうnullableではありません。

問題は、その列でクエリがフィルター処理されたときに、ビューのパフォーマンスがトイレをまっすぐに下がったことでした。

何らかの理由で、ビューの結果列の明示的なCONVERT()はオプティマイザーを台無しにしませんでした(精度が異なるためとにかくそれを行う必要がありました)が、大きなISNULL()ラッパーを追加しました方法。

3
user1664043