88

列を true または false のみにするビューを作成しようとしています。しかし、私が何をしても、SQL Server (2008) は私のビット列が何らかの形で null になる可能性があると信じているようです。

「ステータス」列を持つ「製品」というテーブルがありますINT, NULL。ビューで、Product.Status 列が 3 の場合は BIT 列を true に設定し、それ以外の場合はビット フィールドを false にして、Product の各行の行を返したいと考えています。

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 であってはなりません。この列を強制的に にするために使用できる魔法の SQL トリックはありますかNOT NULL

CAST()の周りを削除するCASEと、列は として正しく設定されますNOT NULLが、列のタイプは に設定されINTます。これは私が望むものではありません。であってほしいBIT。:-)

4

3 に答える 3

154

クエリを少し再配置することで、目的を達成できます。秘訣は、ISNULLSQL 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 例外などを処理するコードを記述する必要はありません。

于 2010-02-24T15:08:18.533 に答える
5

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

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

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

この投稿を見つけて、列の周りに ISNULL() を投げると出来上がり - もう nullable ではありません。

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

何らかの理由で、ビューの結果列の明示的な CONVERT() はオプティマイザーを台無しにしませんでした (精度が異なるため、いずれにせよそうしなければなりませんでした) が、冗長な ISNULL() ラッパーを追加すると、大きな問題が発生しました。仕方。

于 2015-01-14T20:22:08.260 に答える
-3

Select ステートメントでできることは、データベース エンジンがクライアントとして送信するデータを制御することだけです。select ステートメントは、基になるテーブルの構造には影響しません。テーブル構造を変更するには、Alter Table ステートメントを実行する必要があります。

  1. まず、テーブルのそのビット フィールドに現在ヌルがないことを確認します。
  2. 次に、次の ddl ステートメントを実行します。 Alter Table dbo.Product Alter column status bit not null

おっと、あなたがやろうとしているのがビューの出力を制御することだけなら、あなたがやっていることは十分です。構文は、ビューの結果セットの HasStatus 列の出力が実際にはnullにならないことを保証します。常にビット値 = 1 またはビット値 = 0 のいずれかになります。オブジェクト エクスプローラーの表示は気にしないでください...

于 2010-02-24T14:54:24.690 に答える