あなたがCREATE TABLE
CASE
式を使用して計算列を作成する場合、この列のデータ型を明示的に定義しません。
CREATE TABLE OrderDetail
( OrderID INT
, ProductID INT
, Qty INT
, OrderDate DATETIME
, ShipDate DATETIME
, STATUS AS CASE
WHEN shipdate is NULL AND orderdate < DATEADD( dd, -7, GETDATE()) THEN 3
WHEN shipdate is NOT NULL THEN 2
ELSE 1
end
)
GO
SQL Serverはこの列のデータ型をどのように決定しますか?
CASE
式の場合、これは データ型の優先順位が最も高い のブランチです。あなたの例では、3つのブランチはすべて整数として解釈される範囲内のリテラルであるため、列のタイプはint
になります。
_sql_variant_property
_を使用して、リテラル式がどのデータ型であるかを判別できます ここでの私の回答による 。例えば_2147483648
_は、bigint
ではなくnumeric(10,0)
として解釈されます。
質問の場合、SQL Serverは結果の列が_NOT NULL
_になることを認識しますが、計算された式の場合、その効果を得るには式をISNULL
でラップする必要があります。
さらに、データ型の優先順位に依存するのではなく、特定のデータ型を強制する場合は、計算でCONVERT
またはCAST
を使用して強制することができます(すべての潜在的な結果が選択したタイプ)。これは、デフォルトで、意図したよりも広いデータ型になってしまう場合に非常に役立ちます。私が見た中で最も一般的な使用例は、たとえばBITではなくINTになってしまう場合です。
Active1 AS CASE WHEN something THEN 1 ELSE 0 END,
Active2 AS CONVERT(BIT, CASE WHEN something THEN 1 ELSE 0 END)
この場合 Active1
はINT
(4バイト)ですが、Active2
はBIT
です(他のBIT
列に隣接している場合は、1バイト以下になる可能性があります)。