ビュー列を NOT NULL にする方法
-
22-09-2019 - |
質問
列を true または false のみにするビューを作成しようとしています。ただし、何をしても、SQL Server (2008) はビット列が何らかの理由で null になる可能性があると信じているようです。
「Product」という名前のテーブルがあり、「Status」という列があります。 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
. :-)
解決
あなたは、あなたのクエリビットを再配置して欲しいものを達成することができます。トリックはISNULL
は、SQL Serverが結果の値がNULL
になることはありませんことを理解する前に、外にでなければならないことである。
SELECT ISNULL(CAST(
CASE Status
WHEN 3 THEN 1
ELSE 0
END AS bit), 0) AS HasStatus
FROM dbo.Product
ORM に使用しているとき、私は実際にこの便利ですを見つけると、そうでない一つの理由NULL可能タイプにマッピングされた結果の値を求めています。アプリケーションがnullの可能性があることはありませんとしての価値を見ればそれはすべての周りのものを容易にすることができます。そして、あなたがハンドルヌル例外などへの書き込みコードにありません。
他のヒント
参考までに、このメッセージに遭遇した人のために、キャスト/変換の外側に ISNULL() を追加すると、ビューのオプティマイザーが台無しになる可能性があります。
インデックス キーとして同じ値を使用しているが、数値精度の種類が異なる 2 つのテーブルがあり (悪いとは思いますが)、ビューはそれらを結合して最終結果を生成していました。しかし、私たちのミドルウェア コードは特定のデータ型を探しており、ビューには返された列の前後に CONVERT() がありました。
OPと同様に、ビューの結果の列記述子がそれをNULL可能として定義していることに気づき、それが2つのテーブルの主キー/外部キーであると考えていました。なぜ結果を null 許容として定義する必要があるのでしょうか?
この投稿を見つけて、列に ISNULL() を投げたところ、出来上がりました。もう null 値を許容できませんでした。
問題は、クエリがその列でフィルター処理されると、ビューのパフォーマンスが低下することでした。
何らかの理由で、ビューの結果列に対する明示的な CONVERT() はオプティマイザを台無しにしませんでしたが (精度が異なるため、とにかくそうする必要がありました)、冗長な ISNULL() ラッパーを追加すると、大きな問題が発生しました。方法。
Select ステートメントでできることは、データベース エンジンがクライアントとして送信するデータを制御することだけです。select ステートメントは、基になるテーブルの構造には影響しません。テーブル構造を変更するには、Alter Table ステートメントを実行する必要があります。
- まず、テーブル内のそのビット フィールドに現在 null が存在しないことを確認します。
- 次に、次の ddl ステートメントを実行します。
Alter Table dbo.Product Alter column status bit not null
おっと、あなたがやろうとしているのがビューの出力を制御することだけであれば、あなたがやっていることで十分です。構文は、ビューの結果セットの HasStatus 列の出力が実際に 一度もない ヌルになる。それは いつも ビット値 = 1 またはビット値 = 0 のいずれかになります。オブジェクト エクスプローラーが何を言うかは心配しないでください...