CREATE TABLE (Transact-SQL)

新しいテーブルを作成します。

トピック リンク アイコンTransact-SQL 構文表記規則

構文

CREATE TABLE 
    [ database_name . [ schema_name ] . | schema_name . ] table_name 
        ( { <column_definition> | <computed_column_definition> 
                | <column_set_definition> }
        [ <table_constraint> ] [ ,...n ] ) 
    [ ON { partition_scheme_name ( partition_column_name ) | filegroup 
        | "default" } ] 
    [ { TEXTIMAGE_ON { filegroup | "default" } ] 
    [ FILESTREAM_ON { partition_scheme_name | filegroup 
        | "default" } ]
    [ WITH ( <table_option> [ ,...n ] ) ]
[ ; ]

<column_definition> ::=
column_name <data_type>
    [ FILESTREAM ]
    [ COLLATE collation_name ] 

    [ SPARSE ] 

    [ NULL | NOT NULL ]
    [ 
        [ CONSTRAINT constraint_name ] DEFAULT constant_expression ] 
      | [ IDENTITY [ ( seed ,increment ) ] [ NOT FOR REPLICATION ] 
    ]
    [ ROWGUIDCOL ] [ <column_constraint> [ ...n ] ] 
<data type> ::= 
[ type_schema_name . ] type_name 
    [ ( precision [ , scale ] | max | 
        [ { CONTENT | DOCUMENT } ] xml_schema_collection ) ] 

<column_constraint> ::= 

[ CONSTRAINT constraint_name ] 
{     { PRIMARY KEY | UNIQUE } 
        [ CLUSTERED | NONCLUSTERED ] 
        [ 
            WITH FILLFACTOR = fillfactor  
          | WITH ( < index_option > [ , ...n ] ) 
        ] 
        [ ON { partition_scheme_name ( partition_column_name ) 
            | filegroup | "default" } ]
  | [ FOREIGN KEY ] 
        REFERENCES [ schema_name . ] referenced_table_name [ ( ref_column ) ] 
        [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ NOT FOR REPLICATION ] 
  | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) 
} 

<computed_column_definition> ::=
column_name AS computed_column_expression 
[ PERSISTED [ NOT NULL ] ]
[ 
    [ CONSTRAINT constraint_name ]
    { PRIMARY KEY | UNIQUE }
        [ CLUSTERED | NONCLUSTERED ]
        [ 
            WITH FILLFACTOR = fillfactor 
          | WITH ( <index_option> [ , ...n ] )
        ]
    | [ FOREIGN KEY ] 
        REFERENCES referenced_table_name [ ( ref_column ) ] 
        [ ON DELETE { NO ACTION | CASCADE } ] 
        [ ON UPDATE { NO ACTION } ] 
        [ NOT FOR REPLICATION ] 
    | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) 
    [ ON { partition_scheme_name ( partition_column_name ) 
        | filegroup | "default" } ]
] 

<column_set_definition> ::=
column_set_name XML COLUMN_SET FOR ALL_SPARSE_COLUMNS

< table_constraint > ::=
[ CONSTRAINT constraint_name ] 
{ 
    { PRIMARY KEY | UNIQUE } 
        [ CLUSTERED | NONCLUSTERED ] 

                (column [ ASC | DESC ] [ ,...n ] ) 
        [ 
            WITH FILLFACTOR = fillfactor 
           |WITH ( <index_option> [ , ...n ] ) 
        ]
        [ ON { partition_scheme_name (partition_column_name)
            | filegroup | "default" } ] 
    | FOREIGN KEY 
                ( column [ ,...n ] ) 
        REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ] 
        [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ NOT FOR REPLICATION ] 
    | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) 
} 

<table_option> ::=
{
    DATA_COMPRESSION = { NONE | ROW | PAGE }
      [ ON PARTITIONS ( { <partition_number_expression> | <range> } 
            [ , ...n ] ) ]
}

<index_option> ::=
{ 
    PAD_INDEX = { ON | OFF } 
  | FILLFACTOR = fillfactor 
  | IGNORE_DUP_KEY = { ON | OFF } 
  | STATISTICS_NORECOMPUTE = { ON | OFF } 
  | ALLOW_ROW_LOCKS = { ON | OFF} 
  | ALLOW_PAGE_LOCKS ={ ON | OFF} 
  | DATA_COMPRESSION = { NONE | ROW | PAGE }
       [ ON PARTITIONS ( { <partition_number_expression> | <range> } 
       [ , ...n ] ) ]
}
<range> ::= 
<partition_number_expression> TO <partition_number_expression>

引数

  • database_name
    テーブルを作成するデータベースの名前を指定します。database_name には、既存のデータベースを指定する必要があります。指定しない場合、database_name は現在のデータベースに設定されます。現在の接続に対するログインには、database_name で指定されたデータベース内の既存のユーザー ID を関連付け、そのユーザー ID に CREATE TABLE 権限を許可しておく必要があります。

  • schema_name
    新しいテーブルが所属するスキーマの名前です。

  • table_name
    新しいテーブルの名前です。テーブル名は、識別子の規則に従う必要があります。116 文字までしか使用できないローカル一時テーブル名 (名前の先頭に 1 つの番号記号 (#) が付加されます) を除き、table_name には、最大 128 文字を使用できます。

  • column_name
    テーブルの列名です。列名は、識別子の規則に従う必要があり、テーブル内で一意であることが必要です。column_name は 128 文字まで指定できます。timestamp データ型の列では、column_name を省略できます。column_name が指定されていない場合、timestamp 列の名前は、既定値の timestamp になります。

  • computed_column_expression
    計算列の値を定義する式です。計算列は、PERSISTED とマークされていない限り、テーブルに物理的に保存されない仮想列です。計算列は、同じテーブルの他の列を使用した式によって計算されます。たとえば、計算列は cost AS price * qty として定義されます。非計算列の名前、定数、関数、変数、およびこれらを 1 つ以上の演算子によって結合した組み合わせを式にすることができます。サブクエリを式にすることはできません。また、別名データ型を含むこともできません。

    計算列は、選択リスト、WHERE 句、ORDER BY 句、その他標準式が使用できる任意の位置で使用できます。ただし、次の場合は除きます。

    • 計算列は、DEFAULT 制約定義または FOREIGN KEY 制約定義として使用したり、NOT NULL 制約定義と共に使用したりすることはできません。ただし、計算列の値が決定的な式によって定義され、その結果のデータ型がインデックス列で可能な場合、計算列は、インデックスのキー列として、または任意の PRIMARY KEY 制約または UNIQUE 制約の一部として使用できます。

      たとえば、テーブルに整数型の列 ab がある場合、計算列 a+b にはインデックスを作成できますが、計算列 a+DATEPART(dd, GETDATE()) にインデックスを作成することはできません。これは、この計算列の値が次の呼び出しで変更される可能性があるためです。

    • 計算列を INSERT ステートメントまたは UPDATE ステートメントの対象にすることはできません。

    注意注意

    テーブル内の個々の行によって、計算列に関係する列の値が異なることがあるため、計算列の値はすべての行について同じにならないことがあります。

    計算列で NULL 値を許容するかどうかは、使用されている式に基づいてデータベース エンジンによって自動的に決定されます。NULL 値を許容しない列のみの場合でも、ほとんどの式の結果は NULL 値を許容すると見なされます。これは、アンダーフローやオーバーフローによって結果が NULL 値になる場合があるためです。テーブルの任意の計算列で NULL 値が許容されるかどうかを調べるには、COLUMNPROPERTY 関数で AllowsNull プロパティを使用します。NULL 値が許容される式を、NULL 値を許容しない式に変換するには、ISNULL に check_expression 定数を指定します。この定数は、NULL 値の結果の代わりに使用される NULL 以外の値です。計算列では、共通言語ランタイム (CLR) のユーザー定義型の式に基づいて、その型に対する REFERENCES 権限が必要です。

  • PERSISTED
    SQL Server データベース エンジンで、計算値をテーブルに物理的に保存し、依存する計算列のいずれかが更新された場合にその値を更新するように指定します。計算列に PERSISTED とマークすることで、計算列に対し、決定的ではあるが正確ではないインデックスを作成することができます。詳細については、「計算列に対するインデックスの作成」を参照してください。パーティション テーブルのパーティション分割列として使用する計算列は、明示的に PERSISTED とマークする必要があります。PERSISTED が指定されている場合は、computed_column_expression は決定的であることが必要です。

  • ON { <partition_scheme> | filegroup | "default" }
    テーブルが格納されるパーティション構成またはファイル グループを指定します。<partition_scheme> を指定すると、テーブルはパーティション テーブルとなり、各パーティションは <partition_scheme> で指定した 1 つ以上のファイル グループに格納されます。filegroup を指定すると、テーブルは指定されたファイル グループに格納されます。ファイル グループはデータベース内に存在している必要があります。"default" を指定するか、ON をまったく指定しないと、テーブルは既定のファイル グループに格納されます。CREATE TABLE で指定したテーブルの格納方法を後から変更することはできません。

    ON {<partition_scheme> | filegroup | "default"} は、PRIMARY KEY 制約または UNIQUE 制約で指定することもできます。これらの制約はインデックスを作成します。filegroup を指定すると、インデックスは指定されたファイル グループに格納されます。"default" を指定するか、ON をまったく指定しないと、インデックスはテーブルと同じファイル グループに格納されます。PRIMARY KEY 制約または UNIQUE 制約がクラスタ化インデックスを作成する場合、テーブルのデータ ページはインデックスと同じファイル グループに格納されます。CLUSTERED を指定するか、制約によりクラスタ化インデックスを作成し、テーブル定義の <partition_scheme> または filegroup とは異なる <partition_scheme> (またはその逆) を指定すると、制約定義だけが優先され、それ以外は無視されます。

    注意注意

    ここでは、default はキーワードではありません。default は、既定ファイル グループの識別子のため、ON "default" または ON [default] のように区切る必要があります。"default" を指定する場合は、現在のセッションの QUOTED_IDENTIFIER オプションが ON である必要があります。これは既定の設定です。詳細については、「SET QUOTED_IDENTIFIER (Transact-SQL)」を参照してください。

    注意注意

    パーティション テーブルを作成した後、テーブルの LOCK_ESCALATION オプションを AUTO に設定することを検討してください。テーブルではなくパーティション (HoBT) レベルにロックをエスカレートできるようにすることで、同時実行性が向上します。詳細については、「ALTER TABLE (Transact-SQL)」を参照してください。

  • TEXTIMAGE_ON { filegroup| "default" }
    text 列、ntext 列、image 列、xml 列、varchar(max) 列、nvarchar(max) 列、varbinary(max) 列、および CLR ユーザー定義型の列が、指定したファイル グループに格納されることを示すキーワードです。

    テーブル内に値の大きな列がない場合は、TEXTIMAGE_ON は指定できません。<partition_scheme> を指定した場合は、TEXTIMAGE_ON を指定できません。"default" を指定するか、TEXTIMAGE_ON をまったく指定しないと、値の大きな列は既定のファイル グループに格納されます。CREATE TABLE で指定した値の大きな列のデータの格納方法を、後から変更することはできません。

    注意注意

    ここでは、default はキーワードではありません。default は、既定のファイル グループの識別子のため、TEXTIMAGE_ON "default" または TEXTIMAGE_ON [default] のように区切る必要があります。"default" を指定する場合は、現在のセッションの QUOTED_IDENTIFIER オプションが ON である必要があります。これは既定の設定です。詳細については、「SET QUOTED_IDENTIFIER (Transact-SQL)」を参照してください。

  • FILESTREAM_ON { partition_scheme_name | filegroup | "default" }
    FILESTREAM データのファイル グループを指定します。

    テーブルが FILESTREAM データを含んでおり、パーティション分割されている場合、FILESTREAM_ON 句を使用して、FILESTREAM ファイル グループのパーティション構成を指定する必要があります。このパーティション構成では、テーブルのパーティション構成と同じパーティション関数とパーティション列を使用する必要があります。それ以外の場合は、エラーが発生します。

    テーブルがパーティション分割されていない場合、FILESTREAM 列も分割できません。テーブルの FILESTREAM データは、単一のファイル グループに格納する必要があります。このファイル グループは、FILESTREAM_ON 句で指定します。

    テーブルがパーティション分割されておらず、FILESTREAM_ON 句も指定されていない場合、DEFAULT プロパティが設定されている FILESTREAM ファイル グループが使用されます。FILESTREAM ファイル グループがない場合は、エラーが発生します。

    • ON や TEXTIMAGE_ON と同様に、FILESTREAM_ON の CREATE TABLE を使用して設定された値は、次の場合を除いて変更できません。

    • CREATE INDEX ステートメントでヒープをクラスタ化インデックスに変換する。この場合は、異なる FILESTREAM ファイル グループ、パーティション構成、または NULL を指定できます。

    • DROP INDEX ステートメントでクラスタ化インデックスをヒープに変換する。この場合は、異なる FILESTREAM ファイル グループ、パーティション構成、または "default" を指定できます。

    FILESTREAM_ON <filegroup> 句のファイル グループ、またはパーティション構成で指定されている各 FILESTREAM ファイル グループには、ファイルが 1 つ定義されている必要があります。このファイルは、CREATE DATABASE ステートメントまたは ALTER DATABASE ステートメントを使用して定義する必要があります。それ以外の場合は、エラーが発生します。

    関連する FILESTREAM のトピックについては、「FILESTREAM ストレージの設計と実装」を参照してください。

  • [ type_schema_name**.** ] type_name
    列のデータ型と、そのデータ型が所属するスキーマを指定します。データ型は、次のいずれかです。

    • システム データ型。

    • SQL Server のシステム データ型に基づく別名型。別名データ型をテーブル定義の中で使用するには、まず、CREATE TYPE ステートメントで別名データ型を作成する必要があります。別名データ型用の NULL/NOT NULL 割り当ては、CREATE TABLE ステートメントの中で上書きできます。ただし、長さ指定は変更できません。CREATE TABLE ステートメント中の別名データ型の長さは指定できません。

    • CLR ユーザー定義型。CLR ユーザー定義型をテーブル定義の中で使用するには、まず、CREATE TYPE ステートメントで CLR ユーザー定義型を作成する必要があります。CLR ユーザー定義型の列を作成するには、その型に対する REFERENCES 権限が必要です。

    type_schema_name を指定しない場合、SQL Server データベース エンジンは次の順序で type_name を参照します。

    • SQL Server のシステム データ型

    • 現在のデータベースの現在のユーザーの既定のスキーマ

    • 現在のデータベースの dbo スキーマ

  • precision
    指定されるデータ型の有効桁数です。有効桁数の詳細については、「有効桁数、小数点以下桁数、および長さ (Transact-SQL)」を参照してください。

  • scale
    指定されるデータ型の小数点以下桁数です。有効な小数点以下桁数の詳細については、「有効桁数、小数点以下桁数、および長さ (Transact-SQL)」を参照してください。

  • max
    データ型 varchar、nvarchar、および varbinary だけに適用され、2^31 バイトの文字データとバイナリ データ、および 2^30 バイトの Unicode データが格納されます。

  • CONTENT
    column_name 内の xml データ型の各インスタンスに、複数のトップレベル要素を含むことができるように指定します。CONTENT は xml データ型にのみ適用され、xml_schema_collection と共に使用する場合にのみ指定できます。指定しない場合は、CONTENT が既定の動作となります。

  • DOCUMENT
    column_name 内の xml データ型の各インスタンスに、トップレベル要素を 1 つだけ含むことができるように指定します。DOCUMENT は xml データ型にのみ適用され、xml_schema_collection と共に使用する場合にのみ指定できます。

  • xml_schema_collection
    xml データ型だけに適用され、XML スキーマ コレクションと型を関連付けます。スキーマで xml 列を使用するには、まず、CREATE XML SCHEMA COLLECTION を使用してデータベース内にスキーマを作成する必要があります。

  • DEFAULT
    挿入の際に明示的な値を指定しない場合に、列に入力される値を指定します。DEFAULT 定義は、timestamp として定義された列または IDENTITY プロパティを持つ列以外のすべての列に適用できます。ユーザー定義型の列に既定値を指定する場合は、その型で constant_expression 型からユーザー定義型への暗黙的な変換がサポートされている必要があります。テーブルが削除されると、DEFAULT 定義も削除されます。既定値として使用できるのは、文字列などの定数値、システム、ユーザー定義、CLR のいずれかのスカラ関数、または NULL だけです。SQL Server の旧バージョンとの互換性を保つため、DEFAULT に制約名を割り当てることができます。

  • constant_expression
    列の既定値として使用される定数、NULL またはシステム関数です。

  • IDENTITY
    新しい列が ID 列であることを示します。テーブルに行が新しく追加されると、データベース エンジンは列に一意な増分の値を設定します。ID 列は通常、PRIMARY KEY 制約と共に使用され、テーブルの一意な行識別子の役割を果たします。IDENTITY プロパティは、tinyint 型、smallint 型、int 型、bigint 型、decimal(p,0) 型、または numeric(p,0) 型の列に割り当てることができます。ID 列は、1 つのテーブルにつき、1 つだけ作成できます。バインドされた既定値および DEFAULT 制約を ID 列と組み合わせて使用することはできません。seed と increment の両方を指定するか、またはどちらも指定しません。どちらも指定しないときの既定値は (1,1) です。

  • seed
    テーブルに読み込まれる最初の行に使用される値です。

  • increment
    既に読み込まれている前の行の ID 値に加算される増分の値です。

  • NOT FOR REPLICATION
    CREATE TABLE ステートメントでは、IDENTITY プロパティ、FOREIGN KEY 制約、CHECK 制約で NOT FOR REPLICATION 句を指定できます。IDENTITY プロパティでこの句を指定すると、レプリケーション エージェントが挿入を行うときに ID 列の値が増加されません。制約でこの句を指定すると、レプリケーション エージェントが挿入、更新、削除操作を行う際に制約が適用されません。詳細については、「NOT FOR REPLICATION を使用した制約、ID、およびトリガの制御」を参照してください。

  • ROWGUIDCOL
    新しい列が行の GUID 列であることを示します。1 つのテーブルにつき、1 つの uniqueidentifier 列だけを ROWGUIDCOL 列に指定できます。ROWGUIDCOL プロパティを適用すると、$ROWGUID を使用して列を参照できるようになります。ROWGUIDCOL プロパティは uniqueidentifier 列にだけ割り当てることができます。データベースの互換性レベルが 65 以下である場合、ROWGUIDCOL キーワードは無効です。詳細については、「sp_dbcmptlevel (Transact-SQL)」を参照してください。ユーザー定義データ型の列には、ROWGUIDCOL を割り当てることはできません。

    ROWGUIDCOL プロパティは、列に格納されている値の一意性を設定しません。また、ROWGUIDCOL プロパティは、テーブルに挿入される新しい行の値を自動的に生成しません。各列に対して一意な値を生成するには、INSERT ステートメントで NEWID 関数または NEWSEQUENTIALID 関数を使用するか、これらの関数を列の既定値として使用します。

  • SPARSE
    列がスパース列であることを示します。スパース列のストレージは NULL 値用に最適化されます。スパース列を NOT NULL として指定することはできません。スパース列のその他の制限事項と詳細については、「スパース列の使用」を参照してください。

  • FILESTREAM
    varbinary(max) 列でのみ有効です。varbinary(max) BLOB データの FILESTREAM ストレージを指定します。

    また、ROWGUIDCOL 属性を持つ uniqueidentifier データ型の列がテーブルに存在する必要があります。この列では、null 値は許可されず、UNIQUE または PRIMARY KEY 単一列制約を持つ必要があります。列の GUID 値は、データの挿入時にアプリケーションによって、または NEWID () 関数を使用する DEFAULT 制約によって、提供する必要があります。

    テーブルに FILESTREAM 列が定義されているときは、ROWGUIDCOL 列を削除したり関連する制約を変更したりすることはできません。ROWGUIDCOL 列は、最後の FILESTREAM 列が削除された後でのみ削除できます。

    列に対して FILESTREAM ストレージ属性を指定した場合、この列のすべての値がファイル システム上の FILESTREAM データ コンテナに格納されます。

  • COLLATE collation_name
    列の照合順序を指定します。照合順序名には、Windows の照合順序名か SQL の照合順序名を指定できます。collation_name は、データ型が char 型、varchar 型、text 型、nchar 型、nvarchar 型、および ntext 型の列にだけ適用できます。collation_name を指定しないと、列には、ユーザー定義データ型である場合はユーザー定義データ型の照合順序が割り当てられ、ユーザー定義データ型でなければデータベースの既定の照合順序が割り当てられます。

    Windows の照合順序名および SQL の照合順序名の詳細については、「Windows 照合順序名 (Transact-SQL)」および「SQL 照合順序名 (Transact-SQL)」を参照してください。

    COLLATE 句の詳細については、「COLLATE (Transact-SQL)」を参照してください。

  • CONSTRAINT
    PRIMARY KEY 制約、NOT NULL 制約、UNIQUE 制約、FOREIGN KEY 制約、または CHECK 制約の開始を示す省略可能なキーワードです。詳細については、「制約」を参照してください。

  • constraint_name
    制約の名前です。制約名は、テーブルが所属するスキーマ内で一意である必要があります。

  • NULL | NOT NULL
    列で NULL 値を許容するかどうかを指定します。NULL は厳密には制約ではありませんが、NOT NULL と同じように指定することができます。計算列で NOT NULL を指定できるのは、同時に PERSISTED も指定した場合だけです。

  • PRIMARY KEY
    一意なインデックスによって、指定した 1 つ以上の列にエンティティの整合性を設定する制約です。PRIMARY KEY 制約は、1 つのテーブルにつき、1 つだけ作成できます。

  • UNIQUE
    一意なインデックスによって、指定した 1 つ以上の列にエンティティの整合性を持たせる制約です。1 つのテーブルは複数の UNIQUE 制約を持つことができます。

  • CLUSTERED | NONCLUSTERED
    PRIMARY KEY 制約または UNIQUE 制約に対して、クラスタ化インデックスまたは非クラスタ化インデックスを作成することを示します。PRIMARY KEY 制約の既定値は CLUSTERED で、UNIQUE 制約の既定値は NONCLUSTERED です。

    CREATE TABLE ステートメントの中で 1 つの制約だけに CLUSTERED を指定することができます。UNIQUE 制約で CLUSTERED が指定され、PRIMARY KEY 制約も指定した場合には、PRIMARY KEY の既定値は NONCLUSTERED になります。

  • FOREIGN KEY REFERENCES
    1 つ以上の列内のデータに参照整合性を持たせる制約です。FOREIGN KEY 制約では、列内の各値が、参照されるテーブル内のその値に対応する参照される列に存在している必要があります。FOREIGN KEY 制約は、参照されるテーブル内の PRIMARY KEY 制約または UNIQUE 制約である列、または参照されるテーブルの UNIQUE INDEX で参照される列のみを参照できます。計算列の外部キーには、PERSISTED も設定する必要があります。

  • [ schema_name**.**] referenced_table_name]
    FOREIGN KEY 制約で参照されるテーブル名と、そのテーブルが所属するスキーマ名です。

  • **(**ref_column [ ,... n ] )
    FOREIGN KEY 制約によって参照されるテーブルの 1 つの列または列の一覧です。

  • ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
    作成されたテーブルの行が参照関係を持ち、参照される行が親テーブルから削除された場合に、その行に対して実行される操作を指定します。既定値は NO ACTION です。

    • NO ACTION
      NO ACTION を指定すると、データベース エンジンではエラーが発生し、親テーブルでの行の削除操作がロールバックされます。

    • CASCADE
      親テーブルから行が削除された場合に、参照元テーブルからもその行が削除されます。

    • SET NULL
      親テーブル内の対応する行が削除されると、外部キーを構成するすべての値に NULL が設定されます。この制約を実行するには、外部キーの列が NULL 値を使用できる必要があります。

    • SET DEFAULT
      親テーブル内の対応する行が削除されると、外部キーを構成するすべての値に既定値が設定されます。この制約を実行するには、すべての外部キー列に既定値が定義されている必要があります。列が NULL 値を許容し、明示的な既定値が設定されていない場合は、列の既定値として NULL が暗黙的に使用されます。

    論理レコードを使用するマージ パブリケーションにテーブルを含める場合、CASCADE は使用しないでください。論理レコードの詳細については、「論理レコードによる関連行への変更のグループ化」を参照してください。

    該当するテーブルに ON DELETE の INSTEAD OF トリガが既に存在する場合は、ON DELETE CASCADE を定義できません。

    たとえば、AdventureWorks データベースで、ProductVendor テーブルに Vendor テーブルとの参照関係があるとします。外部キー ProductVendor.VendorID は、主キー Vendor.VendorID を参照しています。

    Vendor テーブルの行に対して DELETE ステートメントを実行し、ProductVendor.VendorID に対して ON DELETE CASCADE アクションが指定されている場合は、データベース エンジンは ProductVendor テーブルの 1 つ以上の従属行を調べます。従属行がある場合、ProductVendor テーブルの従属行が、Vendor テーブルで参照される行と共に削除されます。

    これに対し、NO ACTION が指定されている場合、ProductVendor テーブルに Vendor テーブルの行を参照する行が 1 つでもあると、データベース エンジンでエラーが発生し、Vendor 行の削除操作をロールバックします。

  • ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
    変更対象のテーブル内の行が参照関係を持ち、親テーブルで参照先の行が更新された場合、変更対象のテーブル内の行に対して発生する操作を指定します。既定値は NO ACTION です。

    • NO ACTION
      NO ACTION を指定すると、データベース エンジンでエラーが発生し、親テーブルの行の更新操作はロールバックされます。

    • CASCADE
      親テーブルで行が更新された場合に、参照元のテーブルでも対応する行が更新されます。

    • SET NULL
      親テーブル内の対応する行が更新されると、外部キーを構成するすべての値に NULL が設定されます。この制約を実行するには、外部キーの列が NULL 値を使用できる必要があります。

    • SET DEFAULT
      親テーブル内の対応する行が更新されると、外部キーを構成するすべての値に既定値が設定されます。この制約を実行するには、すべての外部キー列に既定値が定義されている必要があります。列が NULL 値を許容し、明示的な既定値が設定されていない場合は、列の既定値として NULL が暗黙的に使用されます。

    論理レコードを使用するマージ パブリケーションにテーブルを含める場合、CASCADE は使用しないでください。論理レコードの詳細については、「論理レコードによる関連行への変更のグループ化」を参照してください。

    変更対象のテーブルに ON UPDATE での INSTEAD OF トリガが既に存在する場合は、ON UPDATE CASCADE を定義できません。

    たとえば、AdventureWorks データベースで、ProductVendor テーブルに Vendor テーブルとの参照関係がある (外部キー ProductVendor.VendorID が主キー Vendor.VendorID を参照している) とします。

    Vendor テーブルの行に対して UPDATE ステートメントを実行し、ProductVendor.VendorID に対して ON UPDATE CASCADE アクションが指定されていると、データベース エンジンは ProductVendor テーブルの 1 つ以上の従属行を調べます。従属行がある場合、ProductVendor テーブルの従属行が、Vendor テーブルで参照される行と共に更新されます。

    これに対し、NO ACTION が指定されている場合、ProductVendor テーブルに Vendor テーブルの行を参照する行が 1 つでもあると、データベース エンジンでエラーが発生し、Vendor 行の更新操作をロールバックします。

  • CHECK
    1 つ以上の列に入力できる値を制限することによってドメインの整合性を設定する制約です。計算列の CHECK 制約には、PERSISTED も設定する必要があります。

  • logical_expression
    TRUE または FALSE を返す論理式です。別名データ型を式に入れることはできません。

  • column
    テーブル制約で使われる、かっこで囲まれた 1 つの列または列リストです。制約定義で使われている列を示します。

  • [ ASC | DESC ]
    テーブル制約に参加している 1 つ以上の列が並べ替えられる順序を指定します。既定値は ASC です。

  • partition_scheme_name
    パーティション テーブルの各パーティションがマップされるファイル グループを定義するパーティション構成の名前を指定します。パーティション構成はデータベース内に存在している必要があります。

  • [ partition_column_name**.** ]
    パーティション テーブルに対して、パーティション分割する列を指定します。ここで指定する列は、partition_scheme_name が使用しているパーティション関数で指定した列と、データ型、長さ、有効桁数が同じであることが必要です。パーティション関数に関与する計算列は、明示的に PERSISTED とマークされている必要があります。

    重要な注意事項重要

    パーティション テーブルのパーティション分割列に加え、ALTER TABLE...SWITCH 操作のソースまたはターゲットとなっているパーティション分割されていないテーブルの列にも、NOT NULL を指定することをお勧めします。こうすることで、パーティション分割列の CHECK 制約で NULL 値のチェックを行う必要がなくなります。詳細については、「パーティションの切り替えを使用した効率的なデータの転送」を参照してください。

  • WITH FILLFACTOR **=**fillfactor
    インデックス データの格納に使用される個々のインデックス ページをデータベース エンジンがどの程度埋めるかを指定します。ユーザー定義の fillfactor 値は、1 ~ 100 の範囲で指定できます。値を指定しない場合の既定値は 0 です。FILL FACTOR 値が 0 と 100 の機能は、まったく同じです。

    重要な注意事項重要

    マニュアルには、WITH FILLFACTOR = fillfactor が PRIMARY KEY 制約または UNIQUE 制約に適用される唯一のインデックス オプションとして記述されていますが、これは旧バージョンとの互換性を維持するために記載されており、将来のリリースではこのような記述はなくなります。

  • column_set_name XML COLUMN_SET FOR ALL_SPARSE_COLUMNS
    列セットの名前を指定します。列セットは、型指定されていない XML 表記であり、テーブルのすべてのスパース列を 1 つにまとめて構造化した出力です。列セットの詳細については、「列セットの使用」を参照してください。

  • < table_option> ::=
    1 つ以上のテーブル オプションを指定します。

  • DATA_COMPRESSION
    指定したテーブル、パーティション番号、またはパーティション範囲に、データ圧縮オプションを指定します。オプションは次のとおりです。

    • NONE
      テーブルまたは指定したパーティションが圧縮されません。

    • ROW
      行の圧縮を使用して、テーブルまたは指定したパーティションが圧縮されます。

    • PAGE
      ページの圧縮を使用して、テーブルまたは指定したパーティションが圧縮されます。

    圧縮の詳細については、「圧縮されたテーブルおよびインデックスの作成」を参照してください。

  • ON PARTITIONS ( { <partition_number_expression> | <range> } [ ,...n ] )
    DATA_COMPRESSION 設定を適用するパーティションを指定します。テーブルがパーティション分割されていない場合に ON PARTITIONS 引数を使用すると、エラーが発生します。ON PARTITIONS 句を指定しないと、パーティション テーブルのすべてのパーティションに対して DATA_COMPRESSION オプションが適用されます。

    <partition_number_expression> は以下の方法で指定できます。

    • ON PARTITIONS (2) などのように、1 つのパーティションのパーティション番号を指定します。

    • ON PARTITIONS (1, 5) などのように、複数のパーティションのパーティション番号をコンマで区切って指定します。

    • ON PARTITIONS (2, 4, 6 TO 8) などのように、範囲と個別のパーティションの両方を指定します。

    <range> は、ON PARTITIONS (6 TO 8) などのように、パーティション番号を TO で区切って指定できます。

    さまざまなパーティションにさまざまな種類のデータ圧縮を設定するには、次のように DATA_COMPRESSION オプションを複数回指定します。

    WITH 
    (
    DATA_COMPRESSION = NONE ON PARTITIONS (1), 
    DATA_COMPRESSION = ROW ON PARTITIONS (2, 4, 6 TO 8), 
    DATA_COMPRESSION = PAGE ON PARTITIONS (3, 5)
    )
    
  • <index_option> ::=
    1 つ以上のインデックス オプションを指定します。これらのオプションの詳細な説明については、「CREATE INDEX (Transact-SQL)」を参照してください。

  • PAD_INDEX = { ON | OFF }
    ON の場合、FILLFACTOR で指定された空き領域の割合が、インデックスの中間レベル ページに適用されます。OFF の場合や、FILLFACTOR 値が指定されていない場合は、中間レベル ページは、中間ページの一連のキーを考慮しつつ、インデックスが持つことのできる最大サイズの行が少なくとも 1 つ格納できる領域を残して、ほぼ容量いっぱいに使用されます。既定値は OFF です。

  • FILLFACTOR **=**fillfactor
    インデックスの作成時や変更時に、データベース エンジンが各インデックス ページのリーフ レベルをどのくらい使用するかを示すパーセンテージを指定します。fillfactor は 1 ~ 100 の整数値です。既定値は 0 です。FILLFACTOR 値 0 と 100 の機能は、まったく同じです。

  • IGNORE_DUP_KEY = { ON | OFF }
    挿入操作で、一意のインデックスに重複するキーの値を挿入しようとしたときのエラー応答を指定します。IGNORE_DUP_KEY オプションは、インデックスが作成または再構築された後の挿入操作のみに適用されます。このオプションは、CREATE INDEXALTER INDEX、または UPDATE の実行には影響しません。既定値は OFF です。

    • ON
      重複したキー値が一意のインデックスに挿入されると、警告メッセージが発行されます。一意性制約に違反する行のみが失敗します。

    • OFF
      重複したキー値が一意のインデックスに挿入されると、エラー メッセージが表示されます。INSERT 操作全体がロールバックされます。

    ビューで作成されるインデックス、一意ではないインデックス、XML インデックス、空間インデックス、およびフィルタ選択されたインデックスに対して、IGNORE_DUP_KEY は ON に設定できません。

    IGNORE_DUP_KEY を表示するには、sys.indexes を使用します。

    旧バージョンと互換性のある構文では、WITH IGNORE_DUP_KEY は WITH IGNORE_DUP_KEY = ON と同じです。

  • STATISTICS_NORECOMPUTE = { ON | OFF }
    ON の場合、古いインデックス統計値は自動的には再計算されません。OFF の場合、統計値の自動的な更新が有効になります。既定値は OFF です。

  • ALLOW_ROW_LOCKS = { ON | OFF }
    ON の場合、インデックスにアクセスするときに行ロックが許可されます。いつ行ロックを使用するかは、データベース エンジンによって決定されます。OFF の場合、行のロックは使用されません。既定値は ON です。

  • ALLOW_PAGE_LOCKS = { ON | OFF }
    ON の場合、インデックスにアクセスするときにページ ロックが許可されます。いつページ ロックを使用するかは、データベース エンジンによって決定されます。OFF の場合、ページ ロックは使用されません。既定値は ON です。

説明

SQL Server 2008 では、各データベースに最大 20 億個のテーブルを持たせることができます。定義された列セットを含む 1 つのテーブルには、非スパース列および計算列の合計数を最大 1,024 として、最大 30,000 列まで持たせることができます。列セットを含まないテーブルの列数は、1,024 列に制限されています。行の数とテーブルの総サイズは、使用可能な記憶領域の量によってのみ制限されます。1 行あたりの最大バイト数は 8,060 です。varchar 型、nvarchar 型、varbinary 型、または sql_variant 型の列を含むテーブルでは、定義されるテーブル幅の合計が 8,060 バイトを超えることがあり、この制限は緩和されます。これらの各列の長さは 8,000 バイトという制限がありますが、合計の幅は、1 テーブル内で 8,060 バイトを超えることができます。詳細については、「8 KB を超える場合の行オーバーフロー データ」を参照してください。

各テーブルは、最大 999 個の非クラスタ化インデックスと 1 個のクラスタ化インデックスを含むことができます。これらのインデックスには、テーブルに対して定義された PRIMARY 制約および UNIQUE 制約をサポートするために生成されたインデックスも含まれます。

一般的にテーブルとインデックスには、一度に 1 エクステントの増分で領域が割り当てられます。テーブルまたはインデックスが作成されると、作成されたテーブルまたはインデックスには、ページが均一エクステントを埋めるのに十分な量になるまで、混合エクステントからページが割り当てられます。ページが均一エクステントを埋めるのに十分な量になった後は、現在割り当てられているエクステントが埋まるたびに新しいエクステントが割り当てられます。テーブルに割り当てられて使用されている領域の大きさに関するレポートを表示するには、sp_spaceused を実行します。

データベース エンジンでは、列定義の中で、DEFAULT、IDENTITY、ROWGUIDCOL または列制約を指定する順序は設定されていません。

テーブルを作成するときに、QUOTED IDENTIFIER オプションが OFF に設定されている場合でも、ON としてテーブルのメタデータ内に格納されます。

一時テーブル

ローカルおよびグローバル一時テーブルを作成できます。ローカル一時テーブルは現在のセッション内でしか使えませんが、グローバル一時テーブルはすべてのセッションで使用できます。一時テーブルをパーティション分割することはできません。

ローカル一時テーブル名の前には 1 つの番号記号 (#) を付加し (#table_name)、グローバル一時テーブル名の前には 2 つの番号記号を付加します (##table_name)。

SQL ステートメントは、CREATE TABLE ステートメントの table_name に指定された値を使用して、一時テーブルを参照します。以下に例を示します。

CREATE TABLE #MyTempTable (cola INT PRIMARY KEY);
INSERT INTO #MyTempTable VALUES (1);

1 つのストアド プロシージャまたはバッチ内で複数の一時テーブルを作成する場合は、それぞれ違う名前で作成する必要があります。

ローカル一時テーブルが、複数ユーザーが同時に実行できるストアド プロシージャまたはアプリケーションで作成される場合、データベース エンジンは、異なるユーザーが作成する個々のテーブルを区別できなければなりません。データベース エンジンは、各ローカル一時テーブル名の末尾に数値サフィックスを内部的に追加することによって、テーブルを区別します。tempdbsysobjects テーブルに格納される一時テーブルのフル ネームは、CREATE TABLE ステートメントで指定されたテーブル名とシステムが生成する数値サフィックスから構成されます。サフィックスを追加する余裕を残すため、ローカル一時テーブル名に指定される table_name の長さは、最大 116 文字に制限されます。

一時テーブルは、DROP TABLE を使用して明示的に削除される場合を除き、有効範囲外になったときに自動的に削除されます。

  • ストアド プロシージャで作成されたローカル一時テーブルは、ストアド プロシージャが終了すると自動的に削除されます。テーブルは、そのテーブルを作成したストアド プロシージャによって実行される任意の入れ子になったストアド プロシージャから参照できます。テーブルは、そのテーブルを作成したストアド プロシージャを呼び出したプロセスから参照することはできません。

  • その他すべてのローカル一時テーブルは、現在のセッションの終了時に自動的に削除されます。

  • グローバル一時テーブルは、テーブルを作成したセッションが終了し、その他すべてのタスクがテーブルの参照をやめたときに自動的に削除されます。タスクとテーブルの間の関連付けは、1 つの Transact-SQL ステートメントが存続する間のみ維持されます。したがって、グローバル一時テーブルは、テーブルを作成したセッションが終了したときに、テーブルを能動的に参照していた最後の Transact-SQL ステートメントが完了したときに削除されます。

ストアド プロシージャまたはトリガの内部で作成されたローカル一時テーブルは、ストアド プロシージャまたはトリガが呼び出される前に作成された一時テーブルと同じ名前にすることができます。ただし、クエリが一時テーブルを参照し、かつ同じ名前の一時テーブルが同時に 2 つ存在する場合、クエリがどちらのテーブルに対して解決されるかは定義されません。入れ子になったストアド プロシージャも、そのプロシージャを呼び出したストアド プロシージャによって作成された一時テーブルと同じ名前を持つ一時テーブルを作成することができます。ただし、入れ子になったプロシージャで作成したテーブルへの解決を変更するためには、呼び出し元プロシージャで作成されたテーブルと同じ構造、同じ列名である必要があります。以下の例を参照してください。

CREATE PROCEDURE dbo.Test2
AS
CREATE TABLE #t(x INT PRIMARY KEY);
INSERT INTO #t VALUES (2);
SELECT Test2Col = x FROM #t;
GO
CREATE PROCEDURE dbo.Test1
AS
CREATE TABLE #t(x INT PRIMARY KEY);
INSERT INTO #t VALUES (1);
SELECT Test1Col = x FROM #t;
EXEC Test2;
GO
CREATE TABLE #t(x INT PRIMARY KEY);
INSERT INTO #t VALUES (99);
GO
EXEC Test1;
GO

以下に結果セットを示します。

(1 row(s) affected)

Test1Col    
----------- 
1           

(1 row(s) affected)

Test2Col    
----------- 
2           

ローカル一時テーブルまたはグローバル一時テーブルを作成する場合、CREATE TABLE の構文では、FOREIGN KEY 制約を除く制約定義をサポートします。一時テーブルで FOREIGN KEY 制約が指定されていると、ステートメントは、制約が省略されたことを示す警告メッセージを返します。テーブルは FOREIGN KEY 制約なしで作成されます。FOREIGN KEY 制約の中で一時テーブルを参照することはできません。

一時テーブルの代わりにテーブル変数を使用することをお勧めします。一時テーブルは、一時テーブル上で明示的にインデックスを作成する必要がある場合、またはテーブルの値が複数のストアド プロシージャや関数にまたがって表示される必要がある場合に便利です。一般的に、テーブル変数はクエリ処理に影響を与えます。詳細については、「table (Transact-SQL)」を参照してください。

パーティション テーブル

CREATE TABLE を使用してパーティション テーブルを作成するには、まず、テーブルをパーティション分割する方法を指定するパーティション関数を作成する必要があります。パーティション関数は、CREATE PARTITION FUNCTION を使用して作成します。次に、パーティション構成を作成する必要があります。パーティション構成では、パーティション関数が示すパーティションを保持するファイル グループを指定します。パーティション構成は、CREATE PARTITION SCHEME を使用して作成します。パーティション テーブルでは、PRIMARY KEY 制約または UNIQUE 制約を別のファイル グループに配置するよう指定できません。詳細については、「パーティション テーブルとパーティション インデックス」を参照してください。

PRIMARY KEY 制約

  • テーブルに含めることができる PRIMARY KEY 制約は 1 つだけです。

  • PRIMARY KEY 制約によって生成されたインデックスが含まれていても、テーブル上のインデックスの数を、非クラスタ化インデックス 999 個、クラスタ化インデックス 1 個より多くすることはできません。

  • PRIMARY KEY 制約に対して CLUSTERED または NONCLUSTERED が指定されていない場合は、UNIQUE 制約にクラスタ化インデックスが指定されていなければ、CLUSTERED が使用されます。

  • PRIMARY KEY 制約中で定義する列はすべて、NOT NULL として定義する必要があります。NULL 値を許容するかどうかを指定しない場合、PRIMARY KEY 制約の影響を受けるすべての列は NOT NULL に設定されます。

  • CLR ユーザー定義型の列に対して主キーを定義する場合は、型の実装でバイナリ順がサポートされている必要があります。詳細については、「CLR ユーザー定義型」を参照してください。

UNIQUE 制約

  • UNIQUE 制約に対して CLUSTERED または NONCLUSTERED が指定されていない場合は、特に指定がない限り、NONCLUSTERED が使用されます。

  • 個々の UNIQUE 制約はインデックスを生成します。UNIQUE 制約の数が増えても、テーブル上のインデックスの数を、非クラスタ化インデックス 999 個、クラスタ化インデックス 1 個より多くすることはできません。

  • CLR ユーザー定義型の列に対して一意の UNIQUE 制約を定義する場合は、型の実装でバイナリ順または演算子順がサポートされている必要があります。詳細については、「CLR ユーザー定義型」を参照してください。

FOREIGN KEY 制約

  • FOREIGN KEY 制約の列に NULL 以外の値を入力するときは、その値が参照される列に存在している必要があります。存在していないと外部キー違反のエラー メッセージが返されます。

  • FOREIGN KEY 制約は、変換元列が指定されている場合を除き、前の列に適用されます。

  • FOREIGN KEY 制約は、同じサーバー上の同じデータベース内のテーブルのみを参照できます。複数のデータベースにまたがる参照整合性は、トリガを使って実装する必要があります。詳細については、「CREATE TRIGGER (Transact-SQL)」を参照してください。

  • FOREIGN KEY 制約は、同じテーブル内の他の列を参照できます。これは、自己参照と呼ばれます。

  • 列レベルの FOREIGN KEY 制約の REFERENCES 句は、参照列を 1 つだけ表示できます。この参照列は、制約が定義されている列と同じデータ型である必要があります。

  • テーブルレベルの FOREIGN KEY 制約の REFERENCES 句は、制約列リスト内の列の数と同じ数の参照列を持っている必要があります。また、各参照列のデータ型は、列リスト内の、参照列に対応する列と同じでなければなりません。

  • timestamp 型の列が外部キーまたは参照されるキーの一部である場合、CASCADE、SET NULL、または SET DEFAULT を指定することはできません。

  • CASCADE、SET NULL、SET DEFAULT および NO ACTION は、互いに参照関係にあるテーブルに対して組み合わせて使用することができます。データベース エンジンが NO ACTION を検出すると、関連する CASCADE、SET NULL および SET DEFAULT 操作が停止されロールバックされます。DELETE ステートメントの実行によって、CASCADE、SET NULL、SET DEFAULT および NO ACTION 操作の組み合わせが適用される場合、データベース エンジンが NO ACTION があるかどうかを調べる前にすべての CASCADE、SET NULL および SET DEFAULT 操作が適用されます。

  • データベース エンジンには、他のテーブルを参照するテーブルに含めることができる FOREIGN KEY 制約の数についても、特定のテーブルを参照する他のテーブルが持つ FOREIGN KEY 制約の数についても、事前定義済みの制限はありません。

    ただし、使用できる FOREIGN KEY 制約の実際の数は、ハードウェア構成やデータベースおよびアプリケーションのデザインにより制限されます。1 つのテーブルに含める FOREIGN KEY 制約は 253 個までとし、253 個以内の FOREIGN KEY 制約から参照することをお勧めします。効率的な制限は、アプリケーションとハードウェアにある程度依存します。データベースやアプリケーションをデザインする際には、FOREIGN KEY 制約を適用することのコストを考慮してください。

  • FOREIGN KEY 制約は一時テーブルには設定されません。

  • FOREIGN KEY 制約は、参照されているテーブルの PRIMARY KEY 制約または UNIQUE 制約の中の列だけを参照できます。

  • CLR ユーザー定義型の列に対して外部キーを定義する場合は、型の実装でバイナリ順がサポートされている必要があります。詳細については、「CLR ユーザー定義型」を参照してください。

  • varchar(max) 型の列は、その列が参照する主キーも varchar(max) 型として定義されている場合にのみ FOREIGN KEY 制約で使用できます。

DEFAULT 定義

  • 1 つの列は DEFAULT 定義を 1 つだけ持つことができます。

  • DEFAULT 定義には、定数値、関数、SQL-92 ニラディック関数または NULL を含めることができます。次の表は、ニラディック関数と、ニラディック関数が INSERT ステートメントの実行中に既定値として返す値を示しています。

    SQL-92 ニラディック関数

    戻り値

    CURRENT_TIMESTAMP

    現在の日付と時刻です。

    CURRENT_USER

    挿入を実行しているユーザーの名前です。

    SESSION_USER

    挿入を実行しているユーザーの名前です。

    SYSTEM_USER

    挿入を実行しているユーザーの名前です。

    USER

    挿入を実行しているユーザーの名前です。

  • DEFAULT 定義内の constant_expression は、テーブル内の他の列、または、他のテーブル、ビュー、あるいはストアド プロシージャを参照できません。

  • timestamp データ型を持つ列や IDENTITY プロパティを持つ列に DEFAULT 定義を作成することはできません。

  • 別名データ型が既定のオブジェクトにバインドされている場合、別名データ型を持つ列に DEFAULT 定義を作成することはできません。

CHECK 制約

  • 列は CHECK 制約をいくつでも持つことが可能で、条件には、AND および OR で結合された複数の論理式を含めることができます。列に対する複数の CHECK 制約は、作成された順に検証されます。

  • 検索条件はブール式によって評価する必要があり、他のテーブルを参照することはできません。

  • 列レベルの CHECK 制約は、制約された列のみを参照でき、テーブルレベルの CHECK 制約は、同じテーブル内の列のみを参照できます。

    CHECK CONSTRAINTS とルールは、INSERT ステートメントと UPDATE ステートメントの実行中のデータの検証という同じ役割を果たします。

  • 列に対して 1 つのルールおよび複数の CHECK 制約がある場合、すべての制限が評価されます。

  • text 列、ntext 列、image 列に対しては CHECK 制約を定義できません。

制約に関する追加情報

  • 制約に対して作成されたインデックスは、DROP INDEX で削除することはできません。ALTER TABLE を使用して制約を削除する必要があります。制約に対して作成され、制約によって使用されるインデックスは、DBCC DBREINDEX を使用して再構築することができます。

  • 制約名は識別子の規則に従う必要があります。ただし、番号記号 (#) で始まることはできません。constraint_name を指定しない場合、この制約にはシステムによって生成された名前が割り当てられます。制約の違反に関するすべてのエラー メッセージには、制約名が表示されます。

  • INSERT ステートメント、UPDATE ステートメントまたは DELETE ステートメントで制約の違反があった場合は、ステートメントが終了します。ただし、SET XACT_ABORT に OFF が設定されている場合は、トランザクション (ステートメントが明示的なトランザクションの一部である場合) の処理は続行されます。SET XACT_ABORT に ON が設定されている場合は、トランザクション全体がロールバックされます。**@@**ERROR システム関数を調べることにより、トランザクション定義付きの ROLLBACK TRANSACTION ステートメントを使用することもできます。

  • ALLOW_ROW_LOCKS が ON かつ ALLOW_PAGE_LOCK が ON の場合、インデックスにアクセスするときに行レベル、ページ レベル、テーブル レベルのロックが許可されます。データベース エンジンは適切なロックを選択し、行ロックまたはページ ロックをテーブル ロックにエスカレートすることができます。詳細については、「ロックのエスカレーション (データベース エンジン)」を参照してください。ALLOW_ROW_LOCKS が OFF かつ ALLOW_PAGE_LOCK が OFF の場合は、インデックスにアクセスするときにテーブル レベルのロックだけが許可されます。インデックスのロックの粒度の構成方法の詳細については、「インデックスのロックのカスタマイズ」を参照してください。

  • テーブルが FOREIGN KEY 制約または CHECK 制約とトリガを持っている場合、制約条件は、トリガが実行される前に評価されます。

テーブルとテーブルの列に関するレポートを表示するには、sp_help または sp_helpconstraint を使用します。テーブルの名前を変更するには、sp_rename を使用します。テーブルに依存するビューとストアド プロシージャに関するレポートを表示するには、sys.dm_sql_referenced_entities および sys.dm_sql_referencing_entities を使用します。

テーブル定義内での NULL 値許容の規則

列に NULL 値を許容するかどうかは、その列にデータとして NULL 値を入力できるかどうかを決めるものです。NULL は 0 でも空白でもありません。NULL は、何も入力されなかった、または明示的な NULL が供給されたことを意味し、通常、値が未知である、または使用できないことを示します。

CREATE TABLE または ALTER TABLE でテーブルを作成または変更すると、データベースとセッションの設定は、列定義で使われているデータ型に NULL 値を許容するかどうかの設定に影響を及ぼし、場合によっては、NULL 値の許容を無効にします。計算列でない場合は、常に列を明示的に NULL または NOT NULL として定義することをお勧めします。ユーザー定義データ型を使用する場合は、データ型に NULL 値を許容するかどうかの既定の設定を列が使用できるようにすることをお勧めします。スパース列では常に NULL を許容する必要があります。

明示的に指定しない場合、列に対して NULL 値を許容するかどうかは以下の表に示す規則に従います。

列のデータ型

規則

別名データ型

データベース エンジンは、データ型が作成されたときに指定された NULL 値を許容するかどうかの設定を使用します。データ型に NULL 値を許容するかどうかの既定の設定を調べるには、sp_help を使用します。

CLR ユーザー定義型 (CLR user-defined type)

NULL 値を許容するかどうかは列の定義によって決まります。

システムから提供されているデータ型

システムから提供されているデータ型にオプションが 1 つしかない場合は、それが優先されます。timestamp データ型は NOT NULL でなければなりません。

SET を使用してセッションの設定が ON に設定されている場合

  • ANSI_NULL_DFLT_ON が ON になっていれば、NULL が割り当てられます。

  • ANSI_NULL_DFLT_OFF が ON になっていれば、NOT NULL が割り当てられます。

  • ALTER DATABASE を使用してデータベース設定が構成されている場合

  • ANSI_NULL_DEFAULT_ON が ON になっていれば、NULL が割り当てられます。

  • ANSI_NULL_DEFAULT_OFF が ON になっていれば、NOT NULL が割り当てられます。

  • ANSI_NULL_DEFAULT のデータベース設定を表示するには、カタログ ビュー sys.databases を使用します。

どちらの ANSI_NULL_DFLT オプションもセッションに設定されていない状態で、データベースが既定値 (ANSI_NULL_DEFAULT が OFF) に設定されていると、既定値である NOT NULL が割り当てられます。

列が計算列の場合、その列に NULL 値を許容するかどうかは、常にデータベース エンジンによって自動的に決定されます。計算列が NULL 値を許容するかどうかを確認するには、COLUMNPROPERTY 関数で AllowsNull プロパティを使用します。

注意注意

SQL Server ODBC ドライバでも Microsoft OLE DB Provider for SQL Server でも、特に指定のない限り ANSI_NULL_DFLT_ON が ON に設定されます。ODBC ユーザーと OLE DB ユーザーは、ODBC データ ソースで、またはアプリケーションで設定される接続の属性またはプロパティを使って、これを構成することができます。

データの圧縮

システム テーブルで圧縮を有効にすることはできません。特に指定しない限り、データ圧縮はテーブルの作成時に NONE に設定されます。範囲外の一連のパーティションまたは単独のパーティションを指定すると、エラーが生成されます。データ圧縮の詳細については、「圧縮されたテーブルおよびインデックスの作成」を参照してください。

圧縮状態の変更による、テーブル、インデックス、またはパーティションへの影響を評価するには、sp_estimate_data_compression_savings ストアド プロシージャを使用します。

権限

データベースの CREATE TABLE 権限と、テーブルを作成するスキーマの ALTER 権限が必要です。

CREATE TABLE ステートメント内の列を CLR ユーザー定義型として定義する場合は、その型の所有権か、その型に対する REFERENCES 権限が必要です。

CREATE TABLE ステートメント内の列に XML スキーマ コレクションが関連付けられている場合は、その XML スキーマ コレクションの所有権か、そのスキーマ コレクションに対する REFERENCES 権限が必要です。

A. PRIMARY KEY 制約を使用する

次の例では、サンプル データベース AdventureWorks 内の Employee テーブルの EmployeeID 列にクラスタ化インデックスを持つ PRIMARY KEY 制約の列定義を示しています。制約名はシステムが提供します。

EmployeeID int
PRIMARY KEY CLUSTERED

B. FOREIGN KEY 制約を使用する

FOREIGN KEY 制約は、他のテーブルを参照するために使用します。外部キーは単一列キーの場合も複数列キーの場合もあります。次の例では、SalesPerson テーブルを参照する SalesOrderHeader テーブルに対する単一列 FOREIGN KEY 制約を示しています。単一列 FOREIGN KEY 制約では、REFERENCES 句のみが必要とされます。

SalesPersonID int NULL
REFERENCES SalesPerson(SalesPersonID)

FOREIGN KEY 句を明示的に使用して、列属性を書き換えることもできます。列名が両方のテーブルで同じである必要はないことに注意してください。

FOREIGN KEY (SalesPersonID) REFERENCES SalesPerson(SalesPersonID)

複数列キー制約はテーブル制約として作成されます。AdventureWorks データベース内の SpecialOfferProduct テーブルには、複数列 PRIMARY KEY が含まれています。次の例は、このキーを他のテーブルから参照する方法を示しています。明示的な制約名は省略可能です。

CONSTRAINT FK_SpecialOfferProduct_SalesOrderDetail FOREIGN KEY
 (ProductID, SpecialOfferID)
REFERENCES SpecialOfferProduct (ProductID, SpecialOfferID)

C. UNIQUE 制約を使用する

UNIQUE 制約は、非主キー列に一意性を設定するために使用します。次の例では、Product テーブルの Name 列が一意でなくてはならないという制限を課しています。

Name nvarchar(100) NOT NULL
UNIQUE NONCLUSTERED

D. DEFAULT 定義を使用する

既定値は (INSERT ステートメントおよび UPDATE ステートメントと組み合わせて使用され)、値が何も提供されていないときに、値を提供します。たとえば、AdventureWorks データベースは、会社内で従業員が行うさまざまな職務を列挙する参照テーブルを含むことができます。各職務の説明を示す列に、実際の説明が明示的に入力されなかったときの説明となる既定の文字列を指定できます。

DEFAULT 'New Position - title not formalized yet'

DEFAULT 定義には、定数の他に関数を含めることができます。次の例を使用すると、エントリの現在の日付が取得できます。

DEFAULT (getdate())

ニラディック関数スキャンの使用により、データ整合性を向上させることもできます。行を挿入したユーザーを追跡するには、USER 用ニラディック関数を使用します。ニラディック関数をかっこで囲まないでください。

DEFAULT USER

E. CHECK 制約を使用する

次の例は、Vendor テーブルの CreditRating 列に入力する値に対する制限を示しています。制約には名前がありません。

CHECK (CreditRating >= 1 and CreditRating <= 5)

この例は、テーブルの列に入力される文字データのパターンを制限する名前付き制約を示しています。

CONSTRAINT CK_emp_id CHECK (emp_id LIKE 
'[A-Z][A-Z][A-Z][1-9][0-9][0-9][0-9][0-9][FM]' 
OR emp_id LIKE '[A-Z]-[A-Z][1-9][0-9][0-9][0-9][0-9][FM]')

この例では、値が特定のリストの範囲内にあるか、特定のパターンに従う必要があるという条件を指定しています。

CHECK (emp_id IN ('1389', '0736', '0877', '1622', '1756')
OR emp_id LIKE '99[0-9][0-9]')

F. 完全なテーブル定義を表示する

次の例は、AdventureWorks データベース内に作成された PurchaseOrderDetail テーブルの完全なテーブル定義とすべての制約定義を示します。例を実行するときには、テーブル スキーマを dbo に変更することに注意してください。

CREATE TABLE [dbo].[PurchaseOrderDetail]
(
    [PurchaseOrderID] [int] NOT NULL
        REFERENCES Purchasing.PurchaseOrderHeader(PurchaseOrderID),
    [LineNumber] [smallint] NOT NULL,
    [ProductID] [int] NULL 
        REFERENCES Production.Product(ProductID),
    [UnitPrice] [money] NULL,
    [OrderQty] [smallint] NULL,
    [ReceivedQty] [float] NULL,
    [RejectedQty] [float] NULL,
    [DueDate] [datetime] NULL,
    [rowguid] [uniqueidentifier] ROWGUIDCOL  NOT NULL
        CONSTRAINT [DF_PurchaseOrderDetail_rowguid] DEFAULT (newid()),
    [ModifiedDate] [datetime] NOT NULL 
        CONSTRAINT [DF_PurchaseOrderDetail_ModifiedDate] DEFAULT (getdate()),
    [LineTotal]  AS (([UnitPrice]*[OrderQty])),
    [StockedQty]  AS (([ReceivedQty]-[RejectedQty])),
CONSTRAINT [PK_PurchaseOrderDetail_PurchaseOrderID_LineNumber]
    PRIMARY KEY CLUSTERED ([PurchaseOrderID], [LineNumber])
    WITH (IGNORE_DUP_KEY = OFF)
) 
ON [PRIMARY];

G. XML スキーマ コレクション型を持つ xml 列のあるテーブルを作成する

次の例では、XML スキーマ コレクション HRResumeSchemaCollection 型の xml 列を持つテーブルを作成します。DOCUMENT キーワードは、column_name 内の xml データ型の各インスタンスに、トップレベル要素を 1 つだけ含むことができるように指定します。

USE AdventureWorks;
GO
CREATE TABLE HumanResources.EmployeeResumes 
   (LName nvarchar(25), FName nvarchar(25), 
    Resume xml( DOCUMENT HumanResources.HRResumeSchemaCollection) );

H. パーティション テーブルを作成する

次の例では、テーブルまたはインデックスを 4 つのパーティションに分割するパーティション関数を作成します。次に、4 つのパーティションをそれぞれ保持するファイル グループを指定するパーティション構成を作成します。最後に、そのパーティション構成を使用するテーブルを作成します。この例では、ファイル グループが既にデータベースに存在していると仮定しています。

CREATE PARTITION FUNCTION myRangePF1 (int)
AS RANGE LEFT FOR VALUES (1, 100, 1000) ;
GO
CREATE PARTITION SCHEME myRangePS1
AS PARTITION myRangePF1
TO (test1fg, test2fg, test3fg, test4fg) ;
GO
CREATE TABLE PartitionTable (col1 int, col2 char(10))
ON myRangePS1 (col1) ;
GO

PartitionTable の列 col1 の値に基づき、各パーティションは次のように割り当てられます。

ファイル グループ

test1fg

test2fg

test3fg

test4fg

パーティション

1

2

3

4

[値]

col 1 <= 1

col1 > 1 AND col1 <= 100

col1 > 100 AND col1 <= 1,000

col1 > 1000

I. 列で uniqueidentifier 型を使用する

次の例では、uniqueidentifier 列を含むテーブルを作成します。この例では、PRIMARY KEY 制約を使って、重複値を挿入するユーザーからテーブルを保護し、DEFAULT 制約で NEWSEQUENTIALID() 関数を使って、新しい行の値を指定します。また、$ROWGUID キーワードを使用して参照できるように、この uniqueidentifier 列に ROWGUIDCOL プロパティを適用します。

CREATE TABLE dbo.Globally_Unique_Data
(guid uniqueidentifier CONSTRAINT Guid_Default DEFAULT NEWSEQUENTIALID() ROWGUIDCOL,
    Employee_Name varchar(60)
CONSTRAINT Guid_PK PRIMARY KEY (guid) );

J. 計算列で式を使用する

次の例は、式 ((low + high)/2) を使用して myavg 計算列を計算する方法を示しています。

CREATE TABLE dbo.mytable 
( low int, high int, myavg AS (low + high)/2 ) ;

K. ユーザー定義型の列に基づく計算列を作成する

次の例では、ユーザー定義型 utf8string として定義された 1 つの列を持つテーブルを作成します。型のアセンブリと型自体が現在のデータベース中に既に作成されていることを前提としています。2 番目の列は utf8string に基づいて定義され、type(class)utf8string のメソッド ToString() を使用して列の値が計算されます。

CREATE TABLE UDTypeTable 
( u utf8string, ustr AS u.ToString() PERSISTED ) ;

L. 計算列で USER_NAME 関数を使用する

次の例では、myuser_name 列で USER_NAME() 関数を使用します。

CREATE TABLE dbo.mylogintable
( date_in datetime, user_id int, myuser_name AS USER_NAME() ) ;

M. FILESTREAM 列を含むテーブルを作成する

次の例では、Photo という FILESTREAM 列を含むテーブルを作成します。テーブルに 1 つ以上の FILESTREAM 列が含まれる場合、テーブルには ROWGUIDCOL 列が 1 つ存在する必要があります。

CREATE TABLE dbo.EmployeePhoto
    (
    EmployeeId int NOT NULL PRIMARY KEY,
    ,Photo varbinary(max) FILESTREAM NULL
    ,MyRowGuidColumn uniqueidentifier NOT NULL ROWGUIDCOL
        UNIQUE DEFAULT NEWID()
    )

N. 行の圧縮を使用するテーブルを作成する

次の例では、行の圧縮を使用するテーブルを作成します。

CREATE TABLE T1 
(c1 int, c2 nvarchar(200) )
WITH (DATA_COMPRESSION = ROW);

その他のデータの圧縮の例については、「圧縮されたテーブルおよびインデックスの作成」を参照してください。

O. スパース列と列セットを含むテーブルを作成する

次の各例では、1 つのスパース列を含むテーブル、および 2 つのスパース列と 1 つの列セットを含むテーブルを作成する方法を示します。これらの例では基本構文を使用します。より複雑な例については、「スパース列の使用」および「列セットの使用」を参照してください。

1 つのスパース列を含むテーブルを作成するには、次のコードを実行します。

CREATE TABLE T1
(c1 int PRIMARY KEY,
C2 varchar(50) SPARSE NULL ) ;

2 つのスパース列と CSet という 1 つの列セットを含むテーブルを作成するには、次のコードを実行します。

CREATE TABLE T1
(c1 int PRIMARY KEY,
C2 varchar(50) SPARSE NULL,
C3 int SPARSE NULL,
CSet XML COLUMN_SET FOR ALL_SPARSE_COLUMNS ) ;