web-dev-qa-db-ja.com

計算列のデータ型は何ですか?

あなたがCREATE TABLECASE式を使用して計算列を作成する場合、この列のデータ型を明示的に定義しません。

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はこの列のデータ型をどのように決定しますか?

19
jrara

CASE式の場合、これは データ型の優先順位が最も高い のブランチです。あなたの例では、3つのブランチはすべて整数として解釈される範囲内のリテラルであるため、列のタイプはintになります。

_sql_variant_property_を使用して、リテラル式がどのデータ型であるかを判別できます ここでの私の回答による 。例えば_2147483648_は、bigintではなくnumeric(10,0)として解釈されます。

質問の場合、SQL Serverは結果の列が_NOT NULL_になることを認識しますが、計算された式の場合、その効果を得るには式をISNULLでラップする必要があります。

15
Martin Smith

さらに、データ型の優先順位に依存するのではなく、特定のデータ型を強制する場合は、計算で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)

この場合 Active1INT(4バイト)ですが、Active2BITです(他のBIT列に隣接している場合は、1バイト以下になる可能性があります)。

23
Aaron Bertrand