特殊なデータ型の使用

このトピックでは、SQL Server で使用できる特殊なデータ型について説明します。特殊なデータ型は他のカテゴリに分類されないデータ型です。SQL Server の特殊なデータ型には、bit、hierarchyid、sql_variant、sysname、table、および timestamp があります。

bit

bit データ型は 0 または 1 を格納する数値データ型です。文字列値 True および False は、次の例に示すように、bit 値に変換できます。

SELECT CONVERT (bit, 'true')
SELECT CONVERT(bit, 'false')

この例では、true を 1 に、false を 0 に変換しています。bit 型のデータは、単一引用符で囲む必要はありません。

hierarchyid

hierarchyid データ型は、階層構造を持つ階層データや階層テーブルの管理に使用します。Transact-SQL コードで階層データを処理するには、hierarchyid 関数を使用します。詳細については、「hierarchyid データ型の使用 (データベース エンジン)」を参照してください。

sql_variant

sql_variant データ型では、各種のデータ型のデータ値を 1 つの列、パラメータ、または変数に格納できます。sql_variant 型の列の各インスタンスには、値と、値を記述するメタデータが記録されます。使用できるメタデータは次のとおりです。

  • 基本データ型

  • 最大サイズ

  • 小数点以下桁数

  • 有効桁数

  • 照合順序

特定の sql_variant 型のインスタンスのメタデータ情報を取得するには、SQL_VARIANT_PROPERTY 関数を使用します。

次の例の 2 番目のテーブルには、sql_variant 列があります。

CREATE TABLE ObjectTable (
   ObjectID int CONSTRAINT PKObjectTable PRIMARY KEY,
   ObjectName nvarchar(80),
   ObjectWeight decimal(10,3),
   ObjectColor nvarchar(20))
CREATE TABLE VariablePropertyTable (
   ObjectID int REFERENCES ObjectTable(ObjectID),
   PropertyName nvarchar(100),
   PropertyValue sql_variant,
   CONSTRAINT PKVariablePropertyTable
   PRIMARY KEY(ObjectID, PropertyName))

sysname

sysname データ型は、オブジェクト名を格納するテーブル列、変数、およびストアド プロシージャ パラメータに使用します。sysname の正確な定義は識別子の規則に関係しています。したがって、SQL Server のインスタンス間で異なることがあります。sysname と nvarchar(128) は、sysname が既定で NOT NULL であることを除いて、機能面では同じです。以前のバージョンの SQL Server では、sysname は varchar(30) として定義されています。

重要な注意事項重要

データベースで大文字と小文字が区別されるか、バイナリ照合順序が使用されている場合、sysname は小文字で表記される場合に限り SQL Server システム データ型として認識されます。

table

table データ型の機能は一時テーブルに似ています。このデータ型は、後の処理で結果セットを格納する場合に使用します。このデータ型を使用できるのは、table 型のローカル変数と、ユーザー定義関数の戻り値を定義する場合だけです。

table 変数または戻り値の定義には、列、各列のデータ型、有効桁数、および小数点以下桁数、オプションの PRIMARY KEY、UNIQUE、NULL、CHECK の各制約の定義が含まれます。ユーザー定義テーブルは、データ型として使用できません。

table 変数に格納された行やユーザー定義関数で返された行の形式は、変数を宣言するか関数を作成するときに定義する必要があります。この構文は CREATE TABLE 構文に基づいています。次に例を示します。

DECLARE @TableVar TABLE (Cola int PRIMARY KEY, Colb char(3))
INSERT INTO @TableVar VALUES (1, 'abc')
INSERT INTO @TableVar VALUES (2, 'def')
SELECT * FROM @TableVar
GO

table 変数、および table を返すユーザー定義関数は、特定の SELECT ステートメントおよび INSERT ステートメントでのみ使用できます。この場合、テーブルは、UPDATE、DELETE、および DECLARE CURSOR の各ステートメントでサポートされています。table 変数、table を返すユーザー定義関数は、その他の Transact-SQL ステートメントでは使用できません。

テーブルに適用されたインデックスや他の制約は、DECLARE 変数または CREATE FUNCTION ステートメントの一部として定義する必要があります。これらは後から適用することができません。CREATE INDEX ステートメントや ALTER TABLE ステートメントでは table 変数およびユーザー定義関数を参照できないためです。

table 変数とユーザー定義関数の定義に使用される構文に関する詳細については、「DECLARE @local_variable (Transact-SQL)」および「CREATE FUNCTION (Transact-SQL)」を参照してください。

timestamp

timestamp データ型は、時間または日付とは無関係です。timestamp 値は、データベース内で行われたデータ変更の相対順序を示す 2 進数です。

キー (特に主キー) には timestamp 型の列を使用しないでください。行が変更されるたびに timestamp 値が変更されるためです。

テーブルでデータ変更が行われた時刻を記録するには、datetime2 データ型または smalldatetime データ型を使用して、変更が行われるときに値を自動的に更新するイベントおよびトリガを記録します。

別名データ型

別名データ型を使用すると、SQL Server の基本データ型 (varchar など) を、特定の用途に合わせてカスタマイズできる説明的な名前と形式に拡張できます。たとえば、次のステートメントでは、datetime データ型に基づき、NULL 値 (NULL) を許容する birthday ユーザー定義データ型を実装します。

EXEC sp_addtype birthday, datetime, 'NULL'

ユーザー定義データ型を実装する場合に基本型を選択するときは注意してください。たとえば、米国では、社会保障番号の形式は nnn-nn-nnnn です。社会保障番号には数字が含まれていますが、その数字は ID を示し、数学的演算の対象ではありません。そのため、次の例に示すように、ユーザー定義の社会保障番号のデータ型を varchar として作成し、テーブルに格納された社会保障番号の形式を適用するように CHECK 制約を作成するのが一般的です。

EXEC sp_addtype SSN, 'VARCHAR(11)', 'NOT NULL'
GO
CREATE TABLE ShowSSNUsage (EmployeeID int PRIMARY KEY, EmployeeSSN SSN, CONSTRAINT CheckSSN CHECK ( EmployeeSSN LIKE '[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]' )
)
GO

SSN 列が通常はインデックス (特にクラスタ化インデックス) のキー列として使用されている場合、代わりに int 基本データ型を使用して SSN ユーザー定義データ型を実装すると、キーのサイズを 11 バイトから 4 バイトに縮小できます。このようなキー サイズの縮小により、データを取得する際のパフォーマンスが向上します。効率よくデータを取得できるようにして CHECK 制約の必要性をなくすことは、SSN 値を表示または変更する際に int から文字形式に変換する余分な処理を行うよりも通常は優れています。