CREATE TABLE (Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

SQL Server と Azure SQL データベース で新しいテーブルを作成します。

Note

Azure Synapse Analytics 構文については、「CREATE TABLE (Azure Synapse Analytics)」を参照してください。

Transact-SQL 構文表記規則

構文オプション

一般的な構文

単純な CREATE TABLE 構文 (オプションを使用していない場合は一般的):

CREATE TABLE
    { database_name.schema_name.table_name | schema_name.table_name | table_name }
    ( { <column_definition> } [ ,... n ] )
[ ; ]

完全な構文

ディスク ベースの CREATE TABLE 構文:

CREATE TABLE
    { database_name.schema_name.table_name | schema_name.table_name | table_name }
    [ AS FileTable ]
    ( { <column_definition>
        | <computed_column_definition>
        | <column_set_definition>
        | [ <table_constraint> ] [ ,... n ]
        | [ <table_index> ] }
          [ ,... n ]
          [ PERIOD FOR SYSTEM_TIME ( system_start_time_column_name
             , system_end_time_column_name ) ]
      )
    [ 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 ]
    [ MASKED WITH ( FUNCTION = 'mask_function' ) ]
    [ [ CONSTRAINT constraint_name ] DEFAULT constant_expression ]
    [ IDENTITY [ ( seed , increment ) ]
    [ NOT FOR REPLICATION ]
    [ GENERATED ALWAYS AS { ROW | TRANSACTION_ID | SEQUENCE_NUMBER } { START | END } [ HIDDEN ] ]
    [ [ CONSTRAINT constraint_name ] {NULL | NOT NULL} ]
    [ ROWGUIDCOL ]
    [ ENCRYPTED WITH
        ( COLUMN_ENCRYPTION_KEY = key_name ,
          ENCRYPTION_TYPE = { DETERMINISTIC | RANDOMIZED } ,
          ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
        ) ]
    [ <column_constraint> [ ,... n ] ]
    [ <column_index> ]

<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 ]
        [ ( <column_name> [ ,... n ] ) ]
        [
            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 )
}

<column_index> ::=
 INDEX index_name [ CLUSTERED | NONCLUSTERED ]
    [ WITH ( <index_option> [ ,... n ] ) ]
    [ ON { partition_scheme_name ( column_name )
         | filegroup_name
         | default
         }
    ]
    [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]

<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 ] )
        ]
        [ ON { partition_scheme_name ( partition_column_name )
        | filegroup | "default" } ]

    | [ 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 )
]

<column_set_definition> ::=
column_set_name XML COLUMN_SET FOR ALL_SPARSE_COLUMNS

<table_constraint> ::=
[ CONSTRAINT constraint_name ]
{
    { PRIMARY KEY | UNIQUE }
        [ CLUSTERED | NONCLUSTERED ]
        ( column_name [ ASC | DESC ] [ ,... n ] )
        [
            WITH FILLFACTOR = fillfactor
           | WITH ( <index_option> [ ,... n ] )
        ]
        [ ON { partition_scheme_name (partition_column_name)
            | filegroup | "default" } ]
    | FOREIGN KEY
        ( column_name [ ,... 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_index> ::=
{
    {
      INDEX index_name [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ]
         ( column_name [ ASC | DESC ] [ ,... n ] )
    | INDEX index_name CLUSTERED COLUMNSTORE [ ORDER (column_name [ , ...n ] ) ]
    | INDEX index_name [ NONCLUSTERED ] COLUMNSTORE ( column_name [ ,... n ] )
    }
    [ INCLUDE ( column_name [ ,... n ] ) ]
    [ WHERE <filter_predicate> ]
    [ WITH ( <index_option> [ ,... n ] ) ]
    [ ON { partition_scheme_name ( column_name )
         | filegroup_name
         | default
         }
    ]
    [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]
}

<table_option> ::=
{
    [ DATA_COMPRESSION = { NONE | ROW | PAGE }
      [ ON PARTITIONS ( { <partition_number_expression> | <range> }
      [ ,... n ] ) ] ]
    [ XML_COMPRESSION = { ON | OFF }
      [ ON PARTITIONS ( { <partition_number_expression> | <range> }
      [ ,... n ] ) ] ]
    [ FILETABLE_DIRECTORY = <directory_name> ]
    [ FILETABLE_COLLATE_FILENAME = { <collation_name> | database_default } ]
    [ FILETABLE_PRIMARY_KEY_CONSTRAINT_NAME = <constraint_name> ]
    [ FILETABLE_STREAMID_UNIQUE_CONSTRAINT_NAME = <constraint_name> ]
    [ FILETABLE_FULLPATH_UNIQUE_CONSTRAINT_NAME = <constraint_name> ]
    [ SYSTEM_VERSIONING = ON
        [ ( HISTORY_TABLE = schema_name.history_table_name
          [ , DATA_CONSISTENCY_CHECK = { ON | OFF } ]
    ) ]
    ]
    [ REMOTE_DATA_ARCHIVE =
      {
        ON [ ( <table_stretch_options> [ ,... n] ) ]
        | OFF ( MIGRATION_STATE = PAUSED )
      }
    ]
    [ DATA_DELETION = ON
          { (
             FILTER_COLUMN = column_name,
             RETENTION_PERIOD = { INFINITE | number { DAY | DAYS | WEEK | WEEKS
                              | MONTH | MONTHS | YEAR | YEARS }
        ) }
    ]
    [ LEDGER = ON [ ( <ledger_option> [ ,... n ] ) ]
    | OFF
    ]
}

<ledger_option>::=
{
    [ LEDGER_VIEW = schema_name.ledger_view_name  [ ( <ledger_view_option> [ ,... n ] ) ]
    [ APPEND_ONLY = ON | OFF ]
}

<ledger_view_option>::=
{
    [ TRANSACTION_ID_COLUMN_NAME = transaction_id_column_name ]
    [ SEQUENCE_NUMBER_COLUMN_NAME = sequence_number_column_name ]
    [ OPERATION_TYPE_COLUMN_NAME = operation_type_id column_name ]
    [ OPERATION_TYPE_DESC_COLUMN_NAME = operation_type_desc_column_name ]
}

<table_stretch_options> ::=
{
    [ FILTER_PREDICATE = { NULL | table_predicate_function } , ]
      MIGRATION_STATE = { OUTBOUND | INBOUND | PAUSED }
 }

<index_option> ::=
{
    PAD_INDEX = { ON | OFF }
  | FILLFACTOR = fillfactor
  | IGNORE_DUP_KEY = { ON | OFF }
  | STATISTICS_NORECOMPUTE = { ON | OFF }
  | STATISTICS_INCREMENTAL = { ON | OFF }
  | ALLOW_ROW_LOCKS = { ON | OFF }
  | ALLOW_PAGE_LOCKS = { ON | OFF }
  | OPTIMIZE_FOR_SEQUENTIAL_KEY = { ON | OFF }
  | COMPRESSION_DELAY = { 0 | delay [ Minutes ] }
  | DATA_COMPRESSION = { NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE }
       [ ON PARTITIONS ( { partition_number_expression | <range> }
       [ ,... n ] ) ]
  | XML_COMPRESSION = { ON | OFF }
      [ ON PARTITIONS ( { <partition_number_expression> | <range> }
      [ ,... n ] ) ] ]
}

<range> ::=
<partition_number_expression> TO <partition_number_expression>

メモリ最適化テーブルの構文

メモリ最適化 CREATE TABLE 構文:

CREATE TABLE
    { database_name.schema_name.table_name | schema_name.table_name | table_name }
    ( { <column_definition>
    | [ <table_constraint> ] [ ,... n ]
    | [ <table_index> ]
      [ ,... n ] }
      [ PERIOD FOR SYSTEM_TIME ( system_start_time_column_name
        , system_end_time_column_name ) ]
)
    [ WITH ( <table_option> [ ,... n ] ) ]
 [ ; ]

<column_definition> ::=
column_name <data_type>
    [ COLLATE collation_name ]
    [ GENERATED ALWAYS AS ROW { START | END } [ HIDDEN ] ]
    [ NULL | NOT NULL ]
    [ [ CONSTRAINT constraint_name ] DEFAULT memory_optimized_constant_expression ]
    | [ IDENTITY [ ( 1, 1 ) ] ]
    [ <column_constraint> ]
    [ <column_index> ]

<data_type> ::=
 [type_schema_name. ] type_name [ (precision [ , scale ]) ]

<column_constraint> ::=
 [ CONSTRAINT constraint_name ]
{
  { PRIMARY KEY | UNIQUE }
      { NONCLUSTERED
        | NONCLUSTERED HASH WITH ( BUCKET_COUNT = bucket_count )
      }
  [ ( <column_name> [ ,... n ] ) ]
  | [ FOREIGN KEY ]
        REFERENCES [ schema_name. ] referenced_table_name [ ( ref_column ) ]
  | CHECK ( logical_expression )
}

<table_constraint> ::=
 [ CONSTRAINT constraint_name ]
{
   { PRIMARY KEY | UNIQUE }
     {
       NONCLUSTERED ( column_name [ ASC | DESC ] [ ,... n ])
       | NONCLUSTERED HASH ( column_name [ ,... n ] ) WITH ( BUCKET_COUNT = bucket_count )
                    }
    | FOREIGN KEY
        ( column_name [ ,... n ] )
        REFERENCES referenced_table_name [ ( ref_column [ ,... n ] ) ]
    | CHECK ( logical_expression )
}

<column_index> ::=
  INDEX index_name
{ [ NONCLUSTERED ] | [ NONCLUSTERED ] HASH WITH ( BUCKET_COUNT = bucket_count ) }

<table_index> ::=
  INDEX index_name
{   [ NONCLUSTERED ] HASH ( column_name [ ,... n ] ) WITH ( BUCKET_COUNT = bucket_count )
  | [ NONCLUSTERED ] ( column_name [ ASC | DESC ] [ ,... n ] )
      [ ON filegroup_name | default ]
  | CLUSTERED COLUMNSTORE [ WITH ( COMPRESSION_DELAY = { 0 | delay [ Minutes ] } ) ]
      [ ON filegroup_name | default ]

}

<table_option> ::=
{
    MEMORY_OPTIMIZED = ON
  | DURABILITY = { SCHEMA_ONLY | SCHEMA_AND_DATA }
  | SYSTEM_VERSIONING = ON [ ( HISTORY_TABLE = schema_name.history_table_name
        [, DATA_CONSISTENCY_CHECK = { ON | OFF } ] ) ]

}

Note

SQL Server 2014 (12.x) 以前のバージョンの Transact-SQL 構文を確認するには、以前のバージョンのドキュメントを参照してください。

引数

database_name

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

schema_name

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

table_name

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

AS FileTable

適用対象: SQL Server 2012 (11.x) 以降。

新しいテーブルを FileTable として作成します。 FileTable には固定スキーマがあるため、列は指定しません。 詳細については、「FileTables」を参照してください。

column_name AS computed_column_expression

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

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

  • FOREIGN KEY 制約または CHECK 制約で使用される計算列は、PERSISTED に設定する必要があります。

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

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

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

Note

テーブル内の各行は、計算列に関係する列に対して異なる値を持つ場合があります。そのため、計算列が各行について同じ値を持たない場合があります。

計算列で NULL 値を許容するかどうかは、使用されている式に基づいてデータベース エンジンによって自動的に決定されます。 null 値を許容しない列しかない場合でも、ほとんどの式の結果は null 値を許容すると見なされます。これは、アンダーフローやオーバーフローによって結果が null 値になる場合があるためです。 テーブルの任意の計算列で NULL 値が許容されるかどうかを調べるには、COLUMNPROPERTY 関数で AllowsNull プロパティを使用します。 NULL 値が許容される式を、NULL 値を許容しない式に変換するには、ISNULLcheck_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 (またはその逆) を指定すると、制約定義だけが優先され、それ以外は無視されます。

Note

このコンテキストでは、default はキーワードではありません。 これは、既定ファイル グループの識別子なので、ON "default" または ON [default] のように区切る必要があります。 "default" を指定する場合は、現在のセッションに対して QUOTED_IDENTIFIER オプションが ON である必要があります。 これが既定の設定です。 詳しくは、「SET QUOTED_IDENTIFIER」をご覧ください。

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

TEXTIMAGE_ON { filegroup | "default" }

text 列、ntext 列、image 列、xml 列、varchar(max) 列、nvarchar(max) 列、varbinary(max)、および CLR ユーザー定義型の列 (geometry 型や geography 型など) が、指定したファイル グループに格納されることを示します。

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

注意

varchar(max)nvarchar(max)varbinary(max)xml および大きな UDT 値は、データ行に直接格納されます。レコードのサイズまで値を格納できますが、サイズの上限は 8,000 バイトです。 値がレコードに収まらない場合には、ポインターが行内に格納され、残りは行外の LOB ストレージ領域に格納されます。 0 は、すべての値がデータ行に直接格納されていることを示す既定値です。

TEXTIMAGE_ON では、"LOB ストレージ領域" の場所のみが変更され、データが行内に格納されている場合は影響しません。 sp_tableoption の large value types out of row オプションを使用すると、LOB 値全体が行外に格納されます。

このコンテキストでは、default はキーワードではありません。 これは、既定ファイル グループの識別子なので、TEXTIMAGE_ON "default" または TEXTIMAGE_ON [default] のように区切る必要があります。 "default" を指定する場合は、現在のセッションに対して QUOTED_IDENTIFIER オプションが ON である必要があります。 これが既定の設定です。 詳しくは、「SET QUOTED_IDENTIFIER」をご覧ください。

FILESTREAM_ON { partition_scheme_name | filegroup | "default" }

適用対象: SQL Server 2008 R2 (10.50.x) 以降。 Azure SQL Database と Azure SQL Managed Instance では、FILESTREAM はサポートされていません。

FILESTREAM データのファイル グループを指定します。

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

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

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

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

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

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

FILESTREAM の関連記事については、バイナリ ラージ オブジェクト - BLOB データに関するページをご覧ください。

[ 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 スキーマ。

メモリ最適化テーブルでサポートされるシステム型の一覧については、「インメモリ OLTP に対してサポートされるデータ型」をご覧ください。

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 またはシステム関数。

  • memory_optimized_constant_expression

    列の既定値として使用できる定数、NULL、またはシステム関数。 ネイティブ コンパイル ストアド プロシージャでサポートされている必要があります。 ネイティブ コンパイル ストアド プロシージャの組み込み関数について詳しくは、「ネイティブ コンパイル T-SQL モジュールでサポートされる機能」をご覧ください。

IDENTITY

新しい列が ID 列であることを指定します。 テーブルに行が新しく追加されると、データベース エンジンは列に一意な増分の値を設定します。 ID 列は通常、PRIMARY KEY 制約と共に使用され、テーブルの一意な行識別子 (ROWID) の役割を果たします。 IDENTITY プロパティは、tinyintsmallintintbigintdecimal(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 列の値は増分されません。 制約でこの句を指定すると、レプリケーション エージェントで挿入、更新、削除操作が行われるときに制約が適用されません。

GENERATED ALWAYS AS { ROW | TRANSACTION_ID | SEQUENCE_NUMBER } { START | END } [ HIDDEN ] [ NOT NULL ]

適用対象: SQL Server 2016 (13.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。

テーブルとその履歴テーブルの行バージョンに関する情報を自動的に記録するために使用される列を指定します (テーブルがシステム バージョン管理され、履歴テーブルがある場合)。 この引数を WITH SYSTEM_VERSIONING = ON パラメーターと共に使用して、システム バージョン管理されたテーブル (テンポラルまたは台帳テーブル) を作成します。 詳細については、更新可能な台帳テーブルに関するページと「テンポラル テーブル」を参照してください。

パラメーター 必須のデータ型 必須の NULL 値の許容 説明
ROW datetime2 START: NOT NULL
END: NOT NULL
行バージョンが有効な開始時刻 (START) または行バージョンが有効な終了時刻 (END) のいずれかです。 この引数を PERIOD FOR SYSTEM_TIME 引数と共に使用して、テンポラル テーブルを作成します。
TRANSACTION_ID bigint START: NOT NULL
END: NULL
適用対象: SQL Server 2022 (16.x) 以降、Azure SQL Database。

行バージョンを作成 (START) または無効化 (END) するトランザクションの ID。 テーブルが台帳テーブルの場合、ID では sys.database_ledger_transactions ビューの行が参照されます
SEQUENCE_NUMBER bigint START: NOT NULL
END: NULL
適用対象: SQL Server 2022 (16.x) 以降、Azure SQL Database。

行バージョンを作成 (START) または削除 (END) する操作のシーケンス番号。 この値は、トランザクション内で一意になっています。

上記のデータ型または NULL 値の許容の要件を満たしていない列を指定しようとすると、システムによってエラーがスローされます。 NULL 値の許容を明示的に指定しない場合は、上記の要件に従って、システムにより列が NULL または NOT NULL と定義されます。

1 つまたは両方の期間列を HIDDEN フラグでマークしてこれらの列を暗黙的に非表示にし、SELECT * FROM <table> でこれらの列の値が返されないようにすることができます。 既定では、期間の列は非表示ではありません。 非表示の列を使用するためには、テンポラル テーブルを直接参照するすべてのクエリで明示的に含める必要があります。 変更する、 HIDDEN を既存のPERIOD列の属性 期間 削除し、別の非表示フラグを再作成する必要があります。

INDEX index_name [ CLUSTERED | NONCLUSTERED ] ( column_name [ ASC | DESC ] [ ,... n ] )

適用対象: SQL Server 2014 (12.x) 以降、および Azure SQL Database。

テーブル上にインデックスを作成することを指定します。 これには、クラスター化インデックスまたは非クラスター化インデックスを指定できます。 インデックスには一覧表示される列が含まれ、昇順、降順のいずれかでデータが並べ替えられます。

INDEX index_name CLUSTERED COLUMNSTORE

適用対象: SQL Server 2014 (12.x) 以降、および Azure SQL Database。

テーブル全体を、列形式で、クラスター化列ストア インデックスを使って格納することを指定します。 これには常に、テーブル内のすべての列が含まれます。 列ストア圧縮の利点を得られるように列が整理されるため、データはアルファベットや数値順に並べ替えられません。

Azure Synapse Analytics、Analytics Platform System (PDW)、および SQL Server 2022 (16.x) 以降のバージョンでは、クラスター化列ストア インデックスの列の順序を決定できます。 詳細については、「大規模なデータ ウェアハウス テーブルに順序付けされたクラスター化列ストア インデックスを使用する」を参照してください

INDEX index_name [ NONCLUSTERED ] COLUMNSTORE ( column_name [ ,... n ] )

適用対象: SQL Server 2014 (12.x) 以降、および Azure SQL Database。

テーブル上に非クラスター化列ストア インデックスを作成することを指定します。 基になるテーブルには、行ストア ヒープまたはクラスター化インデックスを指定するか、クラスター化列ストア インデックスを指定することができます。 すべての場合で、テーブルに非クラスター化列ストア インデックスを作成すると、列のデータの 2 番目のコピーがインデックスに格納されます。

非クラスター化列ストア インデックスは、クラスター化列ストア インデックスとして格納および管理されます。 これも非クラスター化列ストア インデックスと呼ばれます。列を制限することができ、テーブル上のセカンダリ インデックスとして存在するためです。

ON partition_scheme_name ( column_name )

ファイル グループが定義されているパーティション構成を指定します。このファイル グループは、パーティション インデックスのパーティションのマップ先となります。 CREATE PARTITION SCHEME または ALTER PARTITION SCHEME を実行して、パーティション構成がデータベース内に存在するようにする必要があります。 column_name には、パーティション インデックスがパーティション分割される対象の列を指定します。 この列は、partition_scheme_name で使用されているパーティション関数の引数のデータ型、長さ、有効桁数に一致する必要があります。 column_name は、インデックス定義で指定されている列に限定されません。 UNIQUE インデックスをパーティション分割する場合、column_name は一意のキーとして使用されている列から選択する必要がありますが、それ以外の場合はベース テーブルの任意の列を指定できます。 この制限により、データベース エンジンでは、単一のパーティション内だけでキー値の一意性を確認できます。

Note

一意でないクラスター化インデックスをパーティション分割するとき、データベース エンジンでは既定により、まだ指定されていない場合、パーティション分割列がクラスター化インデックス キーのリストに追加されます。 一意でない非クラスター化インデックスをパーティション分割するとき、データベース エンジンでは、まだ指定されていない場合、パーティション分割列がインデックスの非キー列 (付加列) として追加されます。

partition_scheme_name または filegroup が指定されないまま、テーブルがパーティション分割されると、インデックスは基になるテーブルと同じパーティション分割列を使用して、同じパーティション構成に配置されます。

Note

XML インデックスにはパーティション構成を指定できません。 ベース テーブルがパーティション分割される場合、XML インデックスではテーブルと同じパーティション構造が使用されます。

パーティション分割の詳細については、「パーティション テーブルとパーティション インデックス」を参照してください。

ON filegroup_name

指定したファイル グループに、指定したインデックスを作成します。 位置の指定がなく、テーブルまたはビューがパーティション分割されていない場合、インデックスには、基になるテーブルまたはビューと同じファイル グループが使用されます。 ファイル グループは既に存在している必要があります。

ON "default"

既定のファイル グループに、指定したインデックスを作成します。

Note

このコンテキストでは、default はキーワードではありません。 これは、既定ファイル グループの識別子なので、ON "default" または ON [default] のように区切る必要があります。 "default" を指定する場合は、現在のセッションに対して QUOTED_IDENTIFIER オプションが ON である必要があります。 これが既定の設定です。 詳しくは、「SET QUOTED_IDENTIFIER」をご覧ください。

[ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]

適用対象: SQL Server 2008 R2 (10.50.x) 以降。

クラスター化インデックスの作成時に、テーブルの FILESTREAM データの配置を指定します。 FILESTREAM_ON 句を使用すると、異なる FILESTREAM ファイル グループやパーティション構成に FILESTREAM データを移動できます。

filestream_filegroup_name FILESTREAM ファイル グループの名前を指定します。 ファイル グループには、CREATE DATABASE ステートメントまたは ALTER DATABASE ステートメントを使用してファイルが 1 つ定義されている必要があります。それ以外の場合は、エラーが発生します。

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

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

クラスター化インデックスの作成で、テーブルに FILESTREAM 列が含まれていないときは、CREATE INDEX ステートメントに FILESTREAM_ON NULL を指定できます。

詳細については、FILESTREAM に関するページをご覧ください。

ROWGUIDCOL

新しい列が行の GUID 列であることを示します。 1 つのテーブルにつき、1 つの uniqueidentifier 列だけを ROWGUIDCOL 列に指定できます。 ROWGUIDCOL プロパティを適用すると、$ROWGUID を使用して列を参照できるようになります。 ROWGUIDCOL プロパティは uniqueidentifier 列にだけ割り当てることができます。 ユーザー定義データ型の列に ROWGUIDCOL を指定することはできません。

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

ENCRYPTED WITH

Always Encrypted 機能を使って暗号化列を指定します。

  • COLUMN_ENCRYPTION_KEY = key_name

    列の暗号化キーを指定します。 詳細については、CREATE COLUMN ENCRYPTION KEY に関するページをご覧ください。

  • ENCRYPTION_TYPE = { DETERMINISTIC | RANDOMIZED }

    決定論的な暗号化では、任意のプレーン テキスト値に対して常に同じ暗号化された値を生成するメソッドが使用されます。 決定論的な暗号化を使うことにより、等価比較を使った検索や、グループ化、暗号化された値に基づく等価結合を使ったテーブルの結合が可能になりますが、承認されていないユーザーが、暗号化された列のパターンを調べることで暗号化された値に関する情報を推測することも可能になります。 決定論的に暗号化された列で 2 つのテーブルを結合することができるのは、両方の列が同じ列暗号化キーを使って暗号化されている場合のみです。 明確な暗号化では、バイナリ 2 文字型の列の並べ替え順序を持つ列の照合順序を使用する必要があります。

    暗号化をランダム化 は低い予測可能な方法でデータを暗号化するためのメソッドを使用します。 ランダム化された暗号化は、より安全ですが、SQL Server インスタンスでセキュア エンクレーブを使用する Always Encrypted がサポートされる場合を除き、暗号化された列に対する計算とインデックス作成はすべて阻止されます。 詳細については、「セキュア エンクレーブを使用する Always Encrypted」をご覧ください。

    Always Encrypted (セキュア エンクレーブなし) を使用している場合、政府の ID 番号などのパラメーターまたはグループ化パラメーターで検索される列には、決定論的な暗号化を使用します。 ランダム化された暗号化は、他のレコードとグループ化されたり、テーブルの結合に使用されたりせず、関心のある暗号化された列を含む行の検索には他の列 (トランザクション番号など) が使用されるため検索されることのない、クレジット カード番号などのデータに使用します。

    セキュア エンクレーブを使用する Always Encrypted を使用する場合は、ランダム化された暗号化が推奨される暗号化の種類です。

    列は、該当するデータ型である必要があります。

  • ALGORITHM

    適用対象: SQL Server 2016 (13.x) 以降。

    'AEAD_AES_256_CBC_HMAC_SHA_256'である必要があります。

    機能の制約などについて詳しくは、Always Encrypted に関するページをご覧ください。

SPARSE

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

MASKED WITH ( FUNCTION = 'mask_function' )

適用対象: SQL Server 2016 (13.x) 以降。

動的なデータ マスクを指定します。 mask_function マスキング関数は、適切なパラメーターの名前を指定します。 次の 4 つの関数を使用できます。

  • default()
  • email()
  • partial()
  • random()

ALTER ANY MASK 権限が必要です。

関数のパラメーターについては、「動的なデータ マスキング」を参照してください。

FILESTREAM

適用対象: SQL Server 2008 R2 (10.50.x) 以降。

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 は、charvarchartextncharnvarchar、および ntext データ型の列に対してのみ適用可能です。 指定しない場合、ユーザー定義データ型の列である場合は列にユーザー定義データ型の照合順序が割り当てられ、それ以外の場合はデータベースの既定の照合順序が割り当てられます。

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

詳しくは、「COLLATE」をご覧ください。

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 制約では、列内の各値が、参照されるテーブル内の対応する参照される列 (1 つまたは複数) に存在している必要があります。 FOREIGN KEY 制約は、参照されるテーブル内の PRIMARY KEY 制約または UNIQUE 制約である列、または参照されるテーブルの UNIQUE INDEX で参照される列のみを参照できます。 計算列上の外部キーも、PERSISTED とマークする必要があります。

  • [ [ schema_name. ] referenced_table_name ]

    FOREIGN KEY 制約で参照されるテーブル名と、そのテーブルが所属するスキーマ名。

  • ( ref_column [ ,... n ] )

    FOREIGN KEY 制約によって参照されるテーブルの列または列のリスト。

  • ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }

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

  • NO ACTION

    データベース エンジン がエラーを生成し、親テーブルでの行の削除操作がロールバックされます。

  • CASCADE

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

  • SET NULL

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

  • SET DEFAULT

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

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

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

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

    DELETE ステートメントを Vendor テーブルの行で実行した場合、ON DELETE CASCADE アクションが ProductVendor.BusinessEntityID に対して指定されていると、データベース エンジン では 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 は指定しないでください。 論理レコードの詳細については、「論理レコードによる関連行への変更をグループ化」を参照してください。

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

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

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

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

  • CHECK

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

  • logical_expression

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

  • column_name

    テーブル制約で使われる、かっこで囲まれた 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 つにまとめて構造化した出力です。 列セットの詳細については、「 列セットの使用」を参照してください。

PERIOD FOR SYSTEM_TIME ( system_start_time_column_name , system_end_time_column_name )

適用対象: SQL Server 2016 (13.x) 以降、および Azure SQL Database。

レコードの有効期間を記録するためにシステムで使われる列の名前を指定します。 この引数を GENERATED ALWAYS AS ROW { START | END }WITH SYSTEM_VERSIONING = ON 引数と共に使用して、テンポラル テーブルを作成します。 詳細については、「 Temporal Tables」を参照してください。

COMPRESSION_DELAY

適用対象: SQL Server 2016 (13.x) 以降、および Azure SQL Database。

メモリ最適化のために、行が変更されないままテーブル内に留まる必要のある最小時間 (分) を遅延によって指定します。その後、それは列ストア インデックスへの圧縮対象となります。 SQL Server では、圧縮する特定の行がその最終更新時刻に従って選択されます。 たとえば、行が 2 時間の期間に頻繁に変更されている場合は、SQL Server が行を圧縮する前に更新が確実に完了するように COMPRESSION_DELAY = 120 Minutes に設定できます。

ディスク ベースのテーブルの場合は、CLOSED 状態のデルタ行グループがそのデルタ行グループに留まる必要がある最低限の分数が遅延によって指定され、その時間が経過すると、SQL Server は行グループを、圧縮された行グループに圧縮できるようになります。 ディスク ベース テーブルでは個々の行において挿入時間と更新時間が追跡されないため、SQL Server は CLOSED 状態のデルタ行グループに遅延を適用します。

既定値は、0 分です。

COMPRESSION_DELAY を使用する場合の推奨事項については、「列ストアを使用したリアルタイム運用分析の概要」を参照してください

<table_option> ::=

1 つ以上のテーブル オプションを指定します。

DATA_COMPRESSION

指定したテーブル、パーティション番号、またはパーティション範囲に、データ圧縮オプションを指定します。 次のようなオプションがあります。

  • NONE

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

  • ROW

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

  • PAGE

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

  • COLUMNSTORE

    適用対象: SQL Server 2016 (13.x) 以降、および Azure SQL Database。

    非クラスター化列ストアとクラスター化列ストア インデックスの両方を含む列ストア インデックスにのみ適用されます。 COLUMNSTORE では、最も高パフォーマンスの列ストア圧縮で圧縮することを指定します。 これは、一般的な選択です。

  • COLUMNSTORE_ARCHIVE

    適用対象: SQL Server 2016 (13.x) 以降、および Azure SQL Database。

    非クラスター化列ストアとクラスター化列ストア インデックスの両方を含む列ストア インデックスにのみ適用されます。 COLUMNSTORE_ARCHIVE では、テーブルまたはパーティションをより小さなサイズにさらに圧縮します。 これは、アーカイブ用や、ストレージのサイズを減らす必要があり、かつ保存と取得に時間をかける余裕があるその他の状況で使用できます。

詳細については、「 Data Compression」を参照してください。

XML_COMPRESSION

適用対象: SQL Server 2022 (16.x) 以降のバージョン、Azure SQL データベース、および Azure SQL Managed Instance。

テーブル内のすべての xml データ型列に XML 圧縮オプションを指定します。 次のようなオプションがあります。

  • ON

    xml データ型を使用した列が圧縮されます。

  • OFF

    xml データ型を使用した列は圧縮されません。

ON PARTITIONS ( { <partition_number_expression> | [ ,... n ] )

DATA_COMPRESSION または XML_COMPRESSION の設定が適用されるパーティションを指定します。 テーブルがパーティション分割されていない場合に ON PARTITIONS 引数を使用すると、エラーが発生します。 ON PARTITIONS 句を指定しないと、パーティション テーブルのすべてのパーティションに対して DATA_COMPRESSION オプションが適用されます。

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

  • 1 つのパーティションのパーティション番号を提供します。たとえば、ON PARTITIONS (2) のようになります。
  • コンマで区切った複数の個別のパーティションのパーティション番号を提供します。たとえば次のとおりです: ON PARTITIONS (1, 5)
  • 範囲と個別のパーティションの両方を提供します。たとえば次のとおりです: ON PARTITIONS (2, 4, 6 TO 8)

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

さまざまなパーティションにさまざまな種類のデータ圧縮を設定するには、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)
);

また、XML_COMPRESSION オプションを 1 回以上指定できます。次に例を示します。

WITH
(
    XML_COMPRESSION = OFF ON PARTITIONS (1),
    XML_COMPRESSION = ON ON PARTITIONS (2, 4, 6 TO 8),
    XML_COMPRESSION = OFF ON PARTITIONS (3, 5)
);

<index_option> ::=

1 つ以上のインデックス オプションを指定します。 これらのオプションの詳細な説明については、CREATE INDEX に関するページをご覧ください。

PAD_INDEX = { ON | OFF }

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

FILLFACTOR = fillfactor

インデックスの作成時または変更時に、データベース エンジン が各インデックス ページのリーフ レベルをどの程度まで埋めるかを、パーセント値で指定します。 fillfactor 値には、1 ~ 100 の整数値を指定してください。 既定値は 0 です。 FILL FACTOR 値 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_KEYWITH 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 です。

OPTIMIZE_FOR_SEQUENTIAL_KEY = { ON | OFF }

適用対象: SQL Server 2019 (15.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。

最終ページ挿入競合に対して最適化するかどうかを指定します。 既定値は OFF です。 詳細については、CREATE INDEX のページの「シーケンシャル キー」セクションを参照してください。

FILETABLE_DIRECTORY = directory_name

適用対象: SQL Server 2012 (11.x) 以降。

Windows と互換性のある FileTable ディレクトリ名を指定します。 この名前は、データベース内のすべての FileTable ディレクトリ名の中で一意である必要があります。 一意性の比較では、照合順序の設定とは関係なく、大文字と小文字は区別されません。 この値を指定しない場合、FileTable の名前が使用されます。

FILETABLE_COLLATE_FILENAME = { collation_name | database_default }

適用対象: SQL Server 2012 (11.x) 以降。 Azure SQL Database と Azure SQL Managed Instance では、FILETABLE はサポートされていません。

FileTable の Name 列に適用される照合順序の名前を指定します。 照合順序は、Windows オペレーティング システムのファイル名のセマンティクスに準拠するために、大文字と小文字を区別しない設定にする必要があります。 この値が指定されていない場合、データベースの既定の照合順序が使用されます。 データベースの既定の照合順序で大文字と小文字が区別される場合は、エラーが発生し、CREATE TABLE 操作は失敗します。

  • collation_name

    大文字と小文字を区別しない照合順序の名前です。

  • database_default

    データベースの既定の照合順序を使用するように指定します。 この照合順序は、大文字と小文字を区別しないものである必要があります。

FILETABLE_PRIMARY_KEY_CONSTRAINT_NAME = constraint_name

適用対象: SQL Server 2012 (11.x) 以降。 Azure SQL Database と Azure SQL Managed Instance では、FILETABLE はサポートされていません。

FileTable に対して自動的に作成される主キー制約で使用する名前を指定します。 この値が指定されていない場合、システムによって制約の名前が生成されます。

FILETABLE_STREAMID_UNIQUE_CONSTRAINT_NAME = constraint_name

適用対象: SQL Server 2012 (11.x) 以降。 Azure SQL Database と Azure SQL Managed Instance では、FILETABLE はサポートされていません。

FileTable の stream_id 列に対して自動的に作成される一意制約で使用する名前を指定します。 この値が指定されていない場合、システムによって制約の名前が生成されます。

FILETABLE_FULLPATH_UNIQUE_CONSTRAINT_NAME = constraint_name

適用対象: SQL Server 2012 (11.x) 以降。 Azure SQL Database と Azure SQL Managed Instance では、FILETABLE はサポートされていません。

FileTable の parent_path_locator 列と name 列に対して自動的に作成される一意制約で使用する名前を指定します。 この値が指定されていない場合、システムによって制約の名前が生成されます。

SYSTEM_VERSIONING = ON [ ( HISTORY_TABLE = schema_name.history_table_name [ , DATA_CONSISTENCY_CHECK = { ON | OFF } ] ) ]

適用対象: SQL Server 2016 (13.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。

データ型、NULL 値の許容制約、および主キー制約の要件が満たされている場合は、テーブルのシステムのバージョン管理を有効にします。 このシステムによって、システム バージョン管理されたテーブル内の各レコードの履歴が個別の履歴テーブルに記録されます。 HISTORY_TABLE 引数が使用されていない場合、この履歴テーブルの名前は MSSQL_TemporalHistoryFor<primary_table_object_id> になります。 履歴テーブルの作成時に履歴テーブルの名前を指定すると場合、は、スキーマとテーブルの名前を指定する必要があります。

履歴テーブルが存在しない場合、システムにより現在のテーブルと同じファイル グループに現在のテーブルのスキーマに一致する新しい履歴テーブルが生成され、2 つのテーブルの間にリンクが作成されて、履歴テーブルの現在のテーブルに各レコードの履歴をシステムで記録できるようになります。 履歴テーブルには既定では、 PAGE 圧縮します。

HISTORY_TABLE 引数を使ってリンクを作成し、既存の履歴テーブルを使用する場合、現在のテーブルと指定したテーブルの間のリンクが作成されます。 現在のテーブルがパーティション分割されている場合、パーティション分割構成が現在のテーブルから履歴テーブルに自動的にレプリケートされないため、履歴テーブルは既定のファイル グループに作成されます。 既存の履歴テーブルへのリンクを作成する場合は、データの整合性チェックを実行することもできます。 このデータの整合性チェックにより、既存のレコードが重複しないようになります。 データを実行する一貫性チェックが、既定値です。

PERIOD FOR SYSTEM_TIME および GENERATED ALWAYS AS ROW { START | END } 引数と共にこの引数を使い、テーブル上でシステムのバージョン管理を有効にします。 詳細については、「 Temporal Tables」を参照してください。 この引数を WITH LEDGER = ON 引数と共に使用して、更新可能な台帳テーブルを作成します。 既存の履歴テーブルを台帳テーブルと共に使用することはできません。

REMOTE_DATA_ARCHIVE = { ON [ ( table_stretch_options [ ,... n ] ) ] | OFF ( MIGRATION_STATE = PAUSED ) }

適用対象: SQL Server 2016 (13.x) 以降。

Stretch Database が有効または無効になっている新しいテーブルを作成します。 詳細については、「 Stretch Database」を参照してください。

重要

拡張データベースは、SQL Server 2022 (16.x) および Azure SQL Database では非推奨になります。 この機能は、データベース エンジンの将来のバージョンで削除される予定です。 新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションは修正することを検討してください。

テーブルに対して Stretch Database を有効にする

ON を指定してテーブルに対して Stretch を有効にする場合は、必要に応じて、MIGRATION_STATE = OUTBOUND を指定してデータの移行をすぐに開始するか、MIGRATION_STATE = PAUSED を指定してデータの移行を延期することができます。 既定値は MIGRATION_STATE = OUTBOUND です。 テーブルに対して Stretch を有効にする方法については、「データベースに対して Stretch Database を有効にする」を参照してください。

前提条件。 テーブルに対して Stretch を有効にする前に、サーバーおよびデータベースで Stretch を有効にする必要があります。 詳細については、「 Enable Stretch Database for a database」を参照してください。

権限: データベースまたはテーブルの Stretch を有効にするには、db_owner アクセス許可が必要です。 テーブルの Stretch を有効にする場合、テーブルに対する ALTER 権限も必要です。

[ FILTER_PREDICATE = { NULL | predicate } ]

適用対象: SQL Server 2016 (13.x) 以降。

必要に応じて、履歴データと現在のデータの両方を含むテーブルから移行する行を選択するフィルター述語を指定します。 この述語で決定論的インライン テーブル値関数を呼び出す必要があります。 詳しくは、「Enable Stretch Database for a table」および「フィルター関数を使用して移行する行を選択する」をご覧ください。

重要

指定したフィルター述語のパフォーマンスが低いと、データ移行のパフォーマンスも低くなります。 Stretch Database では、CROSS APPLY 演算子を使用してテーブルにフィルター述語を適用します。

フィルター述語を指定しない場合、テーブル全体が移行されます。

フィルター述語を指定する場合は、MIGRATION_STATE も指定する必要があります。

MIGRATION_STATE = { OUTBOUND | INBOUND | PAUSED }

適用対象: SQL Server 2016 (13.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。

  • SQL Server から Azure SQL データベース にデータを移行するには OUTBOUND を指定します。

  • Azure SQL データベース から SQL Server にテーブルのリモート データをコピーして戻し、テーブルに対する Stretch を無効にするには、INBOUND を指定します。 詳細については、「 Stretch Database を無効にして、リモート データを戻す」を参照してください。

    この操作にはデータ転送コストが発生し、キャンセルできません。

  • データの移行を一時停止または延期するには PAUSED を指定します。 詳細については、データ移行の一時停止と再開 - Stretch Database に関するページをご覧ください。

[ DATA_DELETION = ON { ( FILTER_COLUMN = column_name, RETENTION_PERIOD = { INFINITE | number { DAY | DAYS | WEEK | WEEKS | MONTH | MONTHS | YEAR | YEARS } ) } ]

適用対象: Azure SQL Edge "のみ"

データベース内のテーブルの古いデータまたは期限切れのデータに対し、アイテム保持ポリシーを使用したクリーンアップを有効にします。 詳細については、データ保持の有効化と無効化に関するページを参照してください。 データ保持を有効にするには、次のパラメーターを指定します。

  • FILTER_COLUMN = { column_name }

    列を指定します。これは、テーブル内の行が古いかどうかを判断するために使用する必要があります。 フィルター列に使用できるデータ型は次のとおりです。

    • date
    • datetime
    • datetime2
    • smalldatetime
    • datetimeoffset
  • RETENTION_PERIOD = { INFINITE | number {DAY | DAYS | WEEK | WEEKS | MONTH | MONTHS | YEAR | YEARS }}

    テーブルの保持期間のポリシーを指定します。 保持期間は、正の整数値と日付部分の単位を組み合わせて指定します。

MEMORY_OPTIMIZED

適用対象: SQL Server 2014 (12.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。 Azure SQL Managed Instance では、General Purpose 層でのメモリ最適化テーブルはサポートされていません。

値が ON の場合は、テーブルがメモリ最適化されていることを示します。 メモリ最適化テーブルは、トランザクション処理のパフォーマンスの最適化に使用されるインメモリ OLTP 機能の一部です。 インメモリ OLTP の使用を開始するには、「クイック スタート 1: Transact-SQL のパフォーマンスを向上させるインメモリ OLTP テクノロジ」を参照してください。 メモリ最適化テーブルについて詳しくは、「メモリ最適化テーブル」をご覧ください。

既定値の OFF は、テーブルがディスク ベースであることを示します。

DURABILITY

適用対象: SQL Server 2014 (12.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。

SCHEMA_AND_DATA は、テーブルに持続性があり、変更がディスクに保存され、再起動またはフェールオーバー後も存続することを示します。 SCHEMA_AND_DATA が既定値です。

SCHEMA_ONLY は、テーブルに持続性がないことを示します。 データベースを再起動またはフェールオーバーした場合、テーブル スキーマは保存されますが、データの更新内容は保存されません。 DURABILITY = SCHEMA_ONLYMEMORY_OPTIMIZED = ON でのみ使用することができます。

警告

DURABILITY = SCHEMA_ONLY を指定してテーブルを作成した後に、ALTER DATABASE を使用して READ_COMMITTED_SNAPSHOT を変更すると、テーブル内のデータが失われます。

BUCKET_COUNT

適用対象: SQL Server 2014 (12.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。

ハッシュ インデックスに作成されるバケットの数を示します。 ハッシュ インデックスの BUCKET_COUNT の最大値は 1,073,741,824 です。 バケット数について詳しくは、「メモリ最適化テーブルのインデックス」をご覧ください。

BUCKET_COUNT は必須の引数です。

INDEX

適用対象: SQL Server 2014 (12.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。

列インデックスとテーブル インデックスは、CREATE TABLE ステートメントの一部として指定できます。 メモリ最適化テーブルのインデックスの追加と削除について詳しくは、「メモリ最適化テーブルの変更」を参照してください。

  • HASH

    適用対象: SQL Server 2014 (12.x) 以降、Azure SQL Database、および Azure SQL Managed Instance。

    ハッシュ インデックスを作成することを示します。

    ハッシュ インデックスは、メモリ最適化テーブルでのみサポートされます。

LEDGER = ON ( <ledger_option> [ ,... n ] ) | OFF

適用対象: SQL Server 2022 (16.x)、Azure SQL Database、Azure SQL Managed Instance。

Note

ステートメントで台帳テーブルを作成する場合は、ENABLE LEDGER 権限が必要です。

作成されるテーブルが、台帳テーブルである (ON) かそうでない (OFF) かを示します。 既定値は OFF です。 APPEND_ONLY = ON オプションを指定した場合は、システムにより新しい行の挿入のみを許可する追加専用の台帳テーブルが作成されます。 それ以外の場合、システムによって更新可能な台帳テーブルが作成されます。 更新可能な台帳テーブルにも SYSTEM_VERSIONING = ON 引数が必要です。 更新可能な台帳テーブルは、システム バージョン管理されたテーブルである必要があります。 しかし、更新可能な台帳テーブルはテンポラル テーブルである必要はありません (PERIOD FOR SYSTEM_TIME パラメーターは必要ありません)。 履歴テーブルに LEDGER = ON および SYSTEM_VERSIONING = ON が指定されている場合、既存のテーブルが参照されることはありません。

台帳データベース (LEDGER = ON オプションを使用して作成されたデータベース) では、台帳テーブルの作成のみが許可されます。 LEDGER = OFF を使用してテーブルを作成しようとすると、エラーが発生します。 LEDGER = ON を指定しない場合でも、新しい各テーブルは既定で更新可能な台帳テーブルとして作成され、他のすべてのパラメーターについては既定値で作成されます。

更新可能な台帳テーブルには、4 つの GENERATED ALWAYS 列を含む必要があります。1 つの列に次の各引数が定義されます。

  • GENERATED ALWAYS AS TRANSACTION_ID START
  • GENERATED ALWAYS AS TRANSACTION_ID END
  • GENERATED ALWAYS AS SEQUENCE_NUMBER START
  • GENERATED ALWAYS AS SEQUENCE_NUMBER END

追加専用の台帳テーブルには、列を 1 つだけ含む必要があります。それぞれ次の引数が定義されます。

  • GENERATED ALWAYS AS TRANSACTION_ID START
  • GENERATED ALWAYS AS SEQUENCE_NUMBER START

必要な常に生成される列のいずれかが CREATE TABLE ステートメントで定義されておらず、ステートメントに LEDGER = ON が含まれる場合、下記のリストのうち適用可能な列定義を使用して列の追加が、システムによって自動的に試行されます。 既に定義されている列と名前の競合がある場合、システムでエラーが発生します。

[ledger_start_transaction_id] BIGINT GENERATED ALWAYS AS TRANSACTION_ID START HIDDEN NOT NULL
[ledger_end_transaction_id] BIGINT GENERATED ALWAYS AS TRANSACTION_ID END HIDDEN NULL
[ledger_start_sequence_number] BIGINT GENERATED ALWAYS AS SEQUENCE_NUMBER START HIDDEN NOT NULL
[ledger_end_sequence_number] BIGINT GENERATED ALWAYS AS SEQUENCE_NUMBER END HIDDEN NULL

<ledger_view_option> では、システムにより自動的に作成され、テーブルにリンクされる台帳ビューのスキーマと名前が指定されます。 オプションが指定されていない場合、システムでは、作成されるテーブルの名前に _Ledger を追加することによって、台帳ビュー名が生成されます (database_name.schema_name.table_name)。 指定した、または生成された名前のビューが存在する場合、システムでエラーが発生します。 テーブルが更新可能な台帳テーブルである場合は、テーブルとその履歴テーブルの和集合として、台帳ビューが作成されます。

台帳ビューの各行は、台帳テーブルの行バージョンの作成または削除のどちらかを表します。 台帳ビューには、上に示した常に生成される列を除く、台帳テーブルのすべての列が含まれます。 台帳ビューには、次の追加列も含まれます。

列名 データ型 説明
TRANSACTION_ID_COLUMN_NAME オプションを使用して指定します。 指定されていない場合は ledger_transaction_id bigint 行バージョンを作成または削除したトランザクションの ID。
SEQUENCE_NUMBER_COLUMN_NAME オプションを使用して指定します。 指定されていない場合は ledger_sequence_number bigint テーブルに対するトランザクション内の行レベルの操作のシーケンス番号。
OPERATION_TYPE_COLUMN_NAME オプションを使用して指定します。 指定されていない場合は ledger_operation_type tinyint 1 (INSERT) または 2 ()DELETE が含まれます。 台帳テーブルに行を挿入すると、列に 1 が含まれる新しい行が台帳ビューに生成されます。 台帳テーブルから行を削除すると、列に 2 が含まれる新しい行が台帳ビューに生成されます。 台帳テーブルの行を更新すると、2 つの新しい行が台帳ビューに生成されます。 その内 1 つの行には 2 (DELETE) が含まれ、もう 1 つの行にはこの列に 1 (INSERT) が含まれます。
OPERATION_TYPE_DESC_COLUMN_NAME オプションを使用して指定します。 指定されていない場合は ledger_operation_type_desc nvarchar(128) INSERT または DELETE が含まれます。 詳細については、上記を参照してください。

台帳テーブルの作成を含むトランザクションは sys.database_ledger_transactions でキャプチャされます。

<ledger_option> ::=

台帳オプションを指定します。

[ LEDGER_VIEW = schema_name.ledger_view_name [ ( <ledger_view_option> [ ,... n ] ) ]

台帳ビューの名前と、システムによって台帳ビューに追加される追加の列の名前を指定します。

[ APPEND_ONLY = ON | OFF ]

作成される台帳テーブルが追加専用か、更新可能かを指定します。 既定では、 OFFです。

<ledger_view_option> ::=

1 つまたは複数の台帳ビューオプションを指定します。 各台帳ビュー オプションでは、台帳テーブルで定義されている列に加えて、システムによりビューに追加する列の名前が指定されます。

[ TRANSACTION_ID_COLUMN_NAME = transaction_id_column_name ]

行バージョンを作成または削除したトランザクションの ID を格納する列の名前を指定します。 既定の列名は ledger_transaction_id です。

[ SEQUENCE_NUMBER_COLUMN_NAME = sequence_number_column_name ]

テーブルのトランザクション内の行レベル操作のシーケンス番号を格納する列の名前を指定します。 既定の列名は ledger_sequence_number です。

[ OPERATION_TYPE_COLUMN_NAME = operation_type_id column_name ]

操作の種類の ID を格納する列の名前を指定します。 既定の列名は ledger_operation_type です。

[ OPERATION_TYPE_DESC_COLUMN_NAME = operation_type_desc_column_name ]

操作の種類の説明を格納する列の名前を指定します。 既定の列名は ledger_operation_type_desc です。

解説

許容されるテーブル、列、制約、およびインデックスの数については、「SQL Server の最大容量仕様」を参照してください。

一般的にテーブルとインデックスには、一度に 1 エクステントの増分で領域が割り当てられます。 ALTER DATABASESET MIXED_PAGE_ALLOCATION オプションが TRUE に設定されている場合、または常に SQL Server 2016 (13.x) より前である場合は、テーブルまたはインデックスの作成時に、ページが単一エクステントを埋めるのに十分な量になるまで混合エクステントからページが割り当てられます。 ページが単一エクステントを埋めるのに十分な量になった後は、現在割り当てられているエクステントが埋まるたびに新しいエクステントが割り当てられます。 テーブルに割り当てられて使用されている領域の大きさに関するレポートを表示するには、sp_spaceused を実行します。

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

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

一時テーブル

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

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

Transact-SQL ステートメントは、CREATE TABLE ステートメントで table_name に指定した値などを使用することで、一時テーブルを参照します。

CREATE TABLE #MyTempTable (
    col1 INT PRIMARY KEY
);

INSERT INTO #MyTempTable
VALUES (1);

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

一時テーブルを作成またはアクセスするときに schema_name を含めると、無視されます。 すべての一時テーブルは、dbo スキーマで作成されます。

ローカル一時テーブルが、複数のセッションで同時に実行できるストアド プロシージャまたはアプリケーションにより作成される場合、異なるセッションによって作成される個々のテーブルをデータベース エンジンで区別できる必要があります。 データベース エンジンは、各ローカル一時テーブル名の末尾に数値サフィックスを内部的に追加することによって、テーブルを区別します。 tempdbsys.sysobjects テーブルに格納される一時テーブルのフル ネームは、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 制約で一時テーブルを参照することはできません。

名前付き制約のある一時テーブルがユーザー定義トランザクションのスコープ内で作成される場合、一時テーブルを作成するステートメントを実行できるのは、一度に 1 ユーザーだけです。 たとえば、ストアド プロシージャで名前付き主キー制約のある一時テーブルが作成される場合、そのストアド プロシージャを複数のユーザーが同時に実行することはできません。

データベース スコープ グローバル一時テーブル (Azure SQL Database)

SQL Server のグローバル一時テーブル (テーブル名が ## で始まる) は、tempdb に格納され、SQL Server インスタンス全体のすべてのユーザーのセッション間で共有されます。 SQL テーブル型については、前述のテーブルの作成に関するセクションをご覧ください。

Azure SQL Database では、tempdb にも格納されてスコープがデータベース レベルに指定されるグローバル一時テーブルがサポートされています。 これは、グローバル一時テーブルが同じ Azure SQL データベース 内ですべてのユーザーのセッションで共有されることを意味します。 他のデータベースからのユーザー セッションは、グローバル一時テーブルにアクセスできません。

Azure SQL データベース のグローバル一時テーブルは、SQL Server が一時テーブルに使用するのと同じ構文およびセマンティクスに従います。 同様に、グローバル一時ストアド プロシージャも、スコープが Azure SQL データベース 内のデータベース レベルに設定されます。 ローカル一時テーブル (テーブル名が # で始まる) も Azure SQL データベース でサポートされ、SQL Server で使用されるのと同じ構文およびセマンティクスに従います。 一時テーブルに関する上のセクションをご覧ください。

重要

この機能は、Azure SQL データベース で使用できます。

Azure SQL Database のグローバル一時テーブルのトラブルシューティングを行う

tempdb のトラブルシューティングについては、「tempdb の使用状況を監視する方法」を参照してください。

Note

Azure SQL データベース の DMV のトラブルシューティングにアクセスできるのは、サーバー管理者のみです。

アクセス許可

すべてのユーザーがグローバル一時オブジェクトを作成できます。 ユーザーは追加の権限を付与されない限り、自分で作成したオブジェクトにしかアクセスできません。

パーティション テーブル

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

PRIMARY KEY 制約

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

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

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

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

    Note

    メモリ最適化テーブルでは、null 許容型キー列が許可されます。

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

UNIQUE 制約

  • UNIQUE 制約に対して CLUSTERED や NONCLUSTERED が指定されていない場合は、特に指定がない限り、NONCLUSTERED が使用されます。
  • 個々の UNIQUE 制約はインデックスを生成します。 UNIQUE 制約の数が原因で、テーブル上のインデックスの数が、非クラスター化インデックス 999 個、クラスター化インデックス 1 個を超えることはありません。
  • CLR ユーザー定義型の列に対して一意の制約を定義する場合は、型の実装でバイナリまたは演算子ベースの順序をサポートする必要があります。 詳細については、「 CLR ユーザー定義型」を参照してください。

FOREIGN KEY 制約

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

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

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

  • 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 ユーザー定義型」を参照してください。

  • 外部キー リレーションシップに参加する列は、同じ長さと小数点以下桁数で定義する必要があります。

DEFAULT 定義

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

  • DEFAULT 定義には、定数値、関数、SQL 標準ニラディック関数、または 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 制約がある場合、すべての制限が評価されます。

  • textntextimage 列に対しては CHECK 制約を定義できません。

その他の制約情報

  • 制約に対して作成されたインデックスは、DROP INDEX を使用して削除することはできません。ALTER TABLE を使用して制約を削除する必要があります。 制約に対して作成され、制約によって使用されるインデックスは、ALTER INDEX ... REBUILD を使用して再構築できます。 詳細については、「 インデックスの再編成と再構築」を参照してください。
  • 制約名は識別子の規則に従う必要があります。ただし、番号記号 (#) で始めることはできません。 constraint_name が指定されていない場合、この制約にはシステムによって生成された名前が割り当てられます。 制約の違反に関するすべてのエラー メッセージには、制約名が表示されます。
  • INSERT ステートメント、UPDATE ステートメントまたは DELETE ステートメントで制約の違反があった場合は、ステートメントが終了します。 ただし、SET XACT_ABORT が OFF に設定されている場合は、トランザクション (ステートメントが明示的なトランザクションの一部である場合) の処理は続行されます。 SET XACT_ABORT が ON に設定されている場合は、トランザクション全体がロールバックされます。 @@ERROR システム関数を調べることにより、トランザクション定義付きの ROLLBACK TRANSACTION ステートメントを使用することもできます。
  • ALLOW_ROW_LOCKS = ONALLOW_PAGE_LOCK = ON の場合、インデックスにアクセスするとき、行レベル、ページ レベル、テーブル レベルのロックが許可されます。 データベース エンジンは適切なロックを選択し、行ロックまたはページ ロックをテーブル ロックにエスカレートすることができます。 ALLOW_ROW_LOCKS = OFFALLOW_PAGE_LOCK = OFF の場合、インデックスにアクセスするとき、テーブル レベルのロックのみが許可されます。
  • テーブルが FOREIGN KEY または CHECK CONSTRAINTS とトリガーを持っている場合、制約条件は、トリガーが実行される前に評価されます。

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

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

列の NULL 値の許容により、その列でその列内のデータとして null 値 (NULL) が許可されるかどうかが決定されます。 NULL は 0 でも空白でもありません。NULL は、何も入力されなかった、または明示的な NULL が設定されたことを意味し、通常、値が不明であるか、適用できないことを示します。

CREATE TABLE または ALTER TABLE を使用してテーブルを作成または変更すると、データベースとセッションの設定は、列定義で使われているデータ型に NULL 値を許すかどうかの設定に影響を及ぼし、場合によっては、NULL 値を許すかどうかの設定をオーバーライドします。 計算列でない場合は、常に明示的に NULL または NOT NULL として列を定義することをお勧めします。または、ユーザー定義データ型を使用する場合は、データ型の規定の 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 プロパティを使用します。

Note

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

データ圧縮

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

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

アクセス許可

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

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

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

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

すべてのユーザーが tempdb 内に一時テーブルを作成できます。

ステートメントで台帳テーブルを作成する場合は、ENABLE LEDGER 権限が必要です。

A. 列に PRIMARY KEY 制約を作成する

次の例では、Employee テーブルの EmployeeID 列にクラスター化インデックスを持つ PRIMARY KEY 制約の列定義を示しています。 制約名が指定されていないため、制約名はシステムによって提供されます。

CREATE TABLE dbo.Employee (
    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)

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

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

C. UNIQUE 制約を使用する

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

Name NVARCHAR(100) NOT NULL
UNIQUE NONCLUSTERED

D. DEFAULT 定義を使用する

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

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. 完全なテーブル定義を表示する

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

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()
);

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

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

CREATE TABLE dbo.T1
(
    c1 INT,
    c2 NVARCHAR(200)
)
WITH (DATA_COMPRESSION = ROW);

その他のデータ圧縮の例については、「データ圧縮」を参照してください。

O. XML 圧縮を使用するテーブルを作成する

適用対象: SQL Server 2022 (16.x) 以降のバージョン、Azure SQL データベース、および Azure SQL Managed Instance。

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

CREATE TABLE dbo.T1
(
    c1 INT,
    c2 XML
)
WITH (XML_COMPRESSION = ON);

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

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

この例では、1 つのスパース列を含むテーブルを作成します。

CREATE TABLE dbo.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
);

Q. システム バージョン管理されたディスク ベースのテンポラル テーブルを作成する

適用対象: SQL Server 2016 (13.x) 以降、および Azure SQL Database。

次の例では、新しい履歴テーブルにリンクされたテンポラル テーブルを作成する方法と、既存の履歴テーブルにリンクされたテンポラル テーブルを作成する方法を示します。 テンポラル テーブルでは、システムのバージョン管理を有効にするテーブルに対して有効になるように定義された主キーを含める必要があります。 既存のテーブルのシステムのバージョン管理の追加または削除方法を示す例については、「使用例」でシステムのバージョン管理の例をご覧ください。 ユース ケースについては、「テンポラル テーブル」をご覧ください。

この例では、新しい履歴テーブルにリンクされた新しいテンポラル テーブルを作成します。

CREATE TABLE Department
(
    DepartmentNumber CHAR(10) NOT NULL PRIMARY KEY CLUSTERED,
    DepartmentName VARCHAR(50) NOT NULL,
    ManagerID INT NULL,
    ParentDepartmentNumber CHAR(10) NULL,
    ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
    ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON);

この例では、既存の履歴テーブルにリンクされた新しいテンポラル テーブルを作成します。

-- Existing table
CREATE TABLE Department_History
(
    DepartmentNumber CHAR(10) NOT NULL,
    DepartmentName VARCHAR(50) NOT NULL,
    ManagerID INT NULL,
    ParentDepartmentNumber CHAR(10) NULL,
    ValidFrom DATETIME2 NOT NULL,
    ValidTo DATETIME2 NOT NULL
);

-- Temporal table
CREATE TABLE Department
(
    DepartmentNumber CHAR(10) NOT NULL PRIMARY KEY CLUSTERED,
    DepartmentName VARCHAR(50) NOT NULL,
    ManagerID INT NULL,
    ParentDepartmentNumber CHAR(10) NULL,
    ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
    ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.Department_History, DATA_CONSISTENCY_CHECK = ON));

R. システム バージョン管理されたメモリ最適化テンポラル テーブルを作成する

適用対象: SQL Server 2016 (13.x) 以降、および Azure SQL Database。

次の例では、ディスク ベースの新しい履歴テーブルにリンクされた、システム バージョン管理されたメモリ最適化テンポラル テーブルを作成する方法を示します。

この例では、新しい履歴テーブルにリンクされた新しいテンポラル テーブルを作成します。

CREATE SCHEMA History;
GO

CREATE TABLE dbo.Department
(
    DepartmentNumber CHAR(10) NOT NULL PRIMARY KEY NONCLUSTERED,
    DepartmentName VARCHAR(50) NOT NULL,
    ManagerID INT NULL,
    ParentDepartmentNumber CHAR(10) NULL,
    ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
    ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH
(
    MEMORY_OPTIMIZED = ON,
    DURABILITY = SCHEMA_AND_DATA,
    SYSTEM_VERSIONING = ON (HISTORY_TABLE = History.DepartmentHistory)
);

この例では、既存の履歴テーブルにリンクされた新しいテンポラル テーブルを作成します。

-- Existing table
CREATE TABLE Department_History
(
    DepartmentNumber CHAR(10) NOT NULL,
    DepartmentName VARCHAR(50) NOT NULL,
    ManagerID INT NULL,
    ParentDepartmentNumber CHAR(10) NULL,
    ValidFrom DATETIME2 NOT NULL,
    ValidTo DATETIME2 NOT NULL
);

-- Temporal table
CREATE TABLE Department
(
    DepartmentNumber CHAR(10) NOT NULL PRIMARY KEY CLUSTERED,
    DepartmentName VARCHAR(50) NOT NULL,
    ManagerID INT NULL,
    ParentDepartmentNumber CHAR(10) NULL,
    ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
    ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH
(
    SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.Department_History, DATA_CONSISTENCY_CHECK = ON)
);

S. 暗号化された列を含むテーブルを作成する

次の例では、2 つの暗号化された列を含むテーブルを作成します。 詳細については、「 Always Encrypted」を参照してください。

CREATE TABLE Customers (
    CustName NVARCHAR(60)
        ENCRYPTED WITH (
            COLUMN_ENCRYPTION_KEY = MyCEK,
            ENCRYPTION_TYPE = RANDOMIZED,
            ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
        ),
    SSN VARCHAR(11) COLLATE Latin1_General_BIN2
        ENCRYPTED WITH (
            COLUMN_ENCRYPTION_KEY = MyCEK,
            ENCRYPTION_TYPE = DETERMINISTIC ,
            ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
        ),
    Age INT NULL
);

T. インライン フィルターが適用されたインデックスを作成します

インライン フィルターが適用されたインデックスを持つテーブルを作成します。

CREATE TABLE t1
(
    c1 INT,
    index IX1 (c1) WHERE c1 > 0
);

U. インライン インデックスの作成

ディスク ベース テーブルで NONCLUSTERED インラインを使用する方法を次に示します。

CREATE TABLE t1
(
    c1 INT,
    INDEX ix_1 NONCLUSTERED (c1)
);

CREATE TABLE t2
(
    c1 INT,
    c2 INT INDEX ix_1 NONCLUSTERED
);

CREATE TABLE t3
(
    c1 INT,
    c2 INT,
    INDEX ix_1 NONCLUSTERED (c1,c2)
);

V. 匿名で名前付けされた複合主キーを持つ一時テーブルを作成します

匿名で名前付けされた複合主キーを持つテーブルを作成します。 これは、(それぞれが別のセッションにある) 2 つのセッション スコープの一時テーブルが、同じ制約の名前を使用している場合に、実行時の競合を回避するのに役立ちます。

CREATE TABLE #tmp
(
    c1 INT,
    c2 INT,
    PRIMARY KEY CLUSTERED ([c1], [c2])
);
GO

制約を明示的に名付ける場合は、2 つ目のセッションで次のようなエラーが発生します。

Msg 2714, Level 16, State 5, Line 1
There is already an object named 'PK_#tmp' in the database.
Msg 1750, Level 16, State 1, Line 1
Could not create constraint or index. See previous errors.

一時テーブルの名前が一意であるのに対して、制約の名前が一意ではないことが原因で、問題が発生しています。

西 Azure SQL Database でグローバル一時テーブルを使用する

セッション A では、グローバル一時テーブル ##test を Azure SQL Database testdb1 に作成し、1 行を追加します

CREATE TABLE ##test (
    a INT,
    b INT
);

INSERT INTO ##test
VALUES (1, 1);

-- Obtain object ID for temp table ##test
SELECT OBJECT_ID('tempdb.dbo.##test') AS 'Object ID';

結果セットは次のようになります。

1253579504

tempdb (2) で指定されたオブジェクト ID 1253579504 のグローバル一時テーブル名を取得します

SELECT name FROM tempdb.sys.objects WHERE object_id = 1253579504;

結果セットは次のようになります。

##test

セッション B は、Azure SQL データベース testdb1 に接続し、セッション A によって作成されたテーブル ##test にアクセスできます

SELECT * FROM ##test;

結果セットは次のようになります。

1, 1

セッション C は、Azure SQL データベース testdb2 内の別のデータベースに接続し、testdb1 で作成された ##test にアクセスしようとします。 この選択は、グローバル一時テーブルのデータベース スコープが原因で失敗します

SELECT * FROM ##test

これにより、次のエラーが生成されます。

Msg 208, Level 16, State 0, Line 1
Invalid object name '##test'

現在のユーザー データベース testdb1 からの Azure SQL Database tempdb 内のシステム オブジェクトのアドレス指定

SELECT * FROM tempdb.sys.objects;
SELECT * FROM tempdb.sys.columns;
SELECT * FROM tempdb.sys.database_files;

X. テーブルでデータ保持ポリシーを有効にする

次の例では、テーブルを作成してデータ保有を有効にし、保有期間を 1 週間に設定します。 この例は Azure SQL Edge にのみ適用されます。

CREATE TABLE [dbo].[data_retention_table]
(
  [dbdatetime2] datetime2(7),
  [product_code] int,
  [value] char(10)
)
WITH (DATA_DELETION = ON ( FILTER_COLUMN = [dbdatetime2], RETENTION_PERIOD = 1 WEEKS ))

Y. 更新可能な台帳テーブルを作成する

次の例では、匿名の履歴テーブル (システムによって履歴テーブルの名前が生成されます) と生成された台帳ビュー名を持つテンポラル テーブルではない更新可能な台帳テーブルが作成されます。 台帳ビューに必要な常に生成される列の名前と追加の列は指定されていないので、列には既定の名前が含まれます。

CREATE SCHEMA [HR];
GO
CREATE TABLE [HR].[Employees]
(
    EmployeeID INT NOT NULL,
    Salary Money NOT NULL
)
WITH (SYSTEM_VERSIONING = ON, LEDGER = ON);
GO

次の例では、匿名の履歴テーブル (名前はシステムにより生成)、生成された台帳ビュー名、常に生成される列の既定の名前、台帳ビューの追加列を含む、テンポラル テーブルと更新可能な台帳テーブルの両方であるテーブルが作成されます。

CREATE SCHEMA [HR];
GO
CREATE TABLE [HR].[Employees]
(
    EmployeeID INT NOT NULL PRIMARY KEY,
    Salary Money NOT NULL,
    ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
    ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON, LEDGER = ON);
GO

次の例では、明示的な名前の履歴テーブル、ユーザー指定の台帳ビュー名、常に生成される列のユーザー指定の名前、台帳ビューの追加列を含む、テンポラル テーブルと更新可能な台帳テーブルの両方であるテーブルが作成されます。

CREATE SCHEMA [HR];
GO
CREATE TABLE [HR].[Employees]
(
    EmployeeID INT NOT NULL PRIMARY KEY,
    Salary Money NOT NULL,
    StartTransactionId BIGINT GENERATED ALWAYS AS TRANSACTION_ID START HIDDEN NOT NULL,
    EndTransactionId BIGINT GENERATED ALWAYS AS TRANSACTION_ID END HIDDEN NULL,
    StartSequenceNumber BIGINT GENERATED ALWAYS AS SEQUENCE_NUMBER START HIDDEN NOT NULL,
    EndSequenceNumber BIGINT GENERATED ALWAYS AS SEQUENCE_NUMBER END HIDDEN NULL,
    ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
    ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (
    SYSTEM_VERSIONING = ON (HISTORY_TABLE = [HR].[EmployeesHistory]),
    LEDGER = ON (
        LEDGER_VIEW = [HR].[EmployeesLedger] (
            TRANSACTION_ID_COLUMN_NAME = TransactionId,
            SEQUENCE_NUMBER_COLUMN_NAME = SequenceNumber,
            OPERATION_TYPE_COLUMN_NAME = OperationId,
            OPERATION_TYPE_DESC_COLUMN_NAME = OperationTypeDescription
        )
    )
);
GO

次の例では、台帳ビューの生成された名前と台帳ビューの列を含む追加専用の台帳テーブルが作成されます。

CREATE SCHEMA [AccessControl];
GO
CREATE TABLE [AccessControl].[KeyCardEvents]
(
    EmployeeID INT NOT NULL,
    AccessOperationDescription NVARCHAR (MAX) NOT NULL,
    [Timestamp] Datetime2 NOT NULL,
    StartTransactionId BIGINT GENERATED ALWAYS AS TRANSACTION_ID START HIDDEN NOT NULL,
    StartSequenceNumber BIGINT GENERATED ALWAYS AS SEQUENCE_NUMBER START HIDDEN NOT NULL
)
WITH (
    LEDGER = ON (
        LEDGER_VIEW = [AccessControl].[KeyCardEventsLedger] (
            TRANSACTION_ID_COLUMN_NAME = TransactionId,
            SEQUENCE_NUMBER_COLUMN_NAME = SequenceNumber,
            OPERATION_TYPE_COLUMN_NAME = OperationId,
            OPERATION_TYPE_DESC_COLUMN_NAME = OperationTypeDescription
        ),
        APPEND_ONLY = ON
    )
);
GO

次の例では、既定の設定を使用して、Azure SQL Database テーブルの台帳テーブルと更新可能な台帳テーブルが作成されます。 台帳データベースに更新可能な台帳テーブルを作成する場合、WITH (SYSTEM_VERSIONING = ON, LEDGER = ON); を使用する必要はありません。

CREATE DATABASE MyLedgerDB ( EDITION = 'GeneralPurpose' ) WITH LEDGER = ON;
GO

CREATE SCHEMA [HR];
GO

CREATE TABLE [HR].[Employees]
(
    EmployeeID INT NOT NULL,
    Salary Money NOT NULL
)
GO