ALTER DATABASE 互換性レベル (Transact-SQL)

データベースの特定の動作に、指定したバージョンの SQL Server との互換性を設定します。 その他の ALTER DATABASE オプションについては、「ALTER DATABASE (Transact-SQL)」を参照してください。

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

構文

ALTER DATABASE database_name 
SET COMPATIBILITY_LEVEL = { 90 | 100 | 110 }

引数

  • database_name
    変更するデータベースの名前を指定します。

  • COMPATIBILITY_LEVEL {90 | 100 | 110}
    データベースの互換性の対象となる SQL Server のバージョンを指定します。 次のいずれかの値を指定する必要があります。

    90 = SQL Server 2005

    100 = SQL Server 2008 および SQL Server 2008 R2

    110 = SQL Server 2012

説明

SQL Server 2012 のすべてのインストールで、既定の互換性レベルは 110 です。 SQL Server 2012 で作成されたデータベースは、model データベースの互換性レベルがこれより低い場合を除き、このレベルに設定されます。 以前のバージョンの SQL Server から SQL Server 2012 にデータベースをアップグレードした場合、そのデータベースの互換性レベルが 90 以上であれば、既存の互換性レベルがそのまま設定されます。 互換性レベルが 90 を下回るデータベースをアップグレードすると、そのデータベースの互換性レベルは 90 に設定されます。 これはシステム データベースとユーザー データベースの両方に適用されます。 データベースの互換性レベルを変更するには、ALTER DATABASE を使用します。 データベースの現在の互換性レベルを確認するには、sys.databases カタログ ビューの compatibility_level 列をクエリします。

旧バージョンとの互換性を維持するための互換性レベルの使用

互換性レベルは、サーバー全体ではなく、指定したデータベースの動作にのみ影響します。 互換性レベルでは、以前のバージョンの SQL Server との部分的な互換性だけが提供されます。 互換性レベルは、移行時の暫定的な手段として使用してください。互換性レベルの設定により動作を制御することで、バージョン間の動作の違いに対処することができます。 SQL Server 2012 での動作の違いによって既存の SQL Server アプリケーションに影響が生じる場合は、適切に動作するようアプリケーションを変換した後、 ALTER DATABASE を使用して互換性レベルを 100 に変更します。 データベースの新しい互換性設定は、次回データベースが現行になったとき (ログイン時に既定のデータベースとして使用されるか、USE ステートメントで指定されたとき) に有効になります。

ベスト プラクティス

ユーザーがデータベースに接続しているときに互換性レベルを変更すると、アクティブなクエリに対し誤った結果セットが生成される可能性があります。 たとえば、クエリ プランのコンパイル中に互換性レベルを変更すると、コンパイルされるプランは変更前の互換性レベルと変更後の互換性レベルの両方に基づいてしまう場合があります。その結果、誤ったプランが生成され、不正確な結果が発生する可能性があります。 さらに、プランがプラン キャッシュに置かれ後続のクエリにより再使用された場合、問題が複雑になることが考えられます。 不正確なクエリ結果を避けるため、データベースの互換性レベルを変更するときには次の手順に従うことをお勧めします。

  1. ALTER DATABASE SET SINGLE_USER を使用してデータベースをシングル ユーザー アクセス モードに設定します。

  2. データベースの互換性レベルを変更します。

  3. ALTER DATABASE SET MULTI_USER を使用してデータベースをマルチユーザー アクセス モードにします。

  4. データベースのアクセス モードの設定に関する詳細については、「ALTER DATABASE (Transact-SQL)」を参照してください。

互換性レベルとストアド プロシージャ

ストアド プロシージャを実行すると、そのストアド プロシージャが定義されているデータベースの現在の互換性レベルが使用されます。 データベースの互換性設定が変更された場合、そのデータベースのすべてのストアド プロシージャは、設定に合わせて自動的に再コンパイルされます。

互換性レベル 90 とレベル 100 の相違点

ここでは、互換性レベル 100 に導入された新しい動作について説明します。

互換性レベル設定 90

互換性レベル設定 100

影響度

複数ステートメントのテーブル値関数が作成されるとき、QUOTED_IDENTIFER 設定はセッション レベルの設定に関係なく常に ON に設定されます。

複数ステートメントのテーブル値関数が作成されるとき、QUOTED IDENTIFIER のセッション設定が受け入れられます。

パーティション関数を作成または変更するとき、関数の datetime リテラルおよび smalldatetime リテラルは、言語設定が US_English であることを前提に評価されます。

パーティション関数の datetime リテラルおよび smalldatetime リテラルを評価する際、現在の言語設定が使用されます。

INSERT ステートメントと SELECT INTO ステートメントで FOR BROWSE 句は許可されます (ただし無視されます)。

INSERT ステートメントと SELECT INTO ステートメントで FOR BROWSE 句は許可されません。

OUTPUT 句でフルテキスト述語を使用できます。

OUTPUT 句でフルテキスト述語を使用できません。

CREATE FULLTEXT STOPLIST、ALTER FULLTEXT STOPLIST、および DROP FULLTEXT STOPLIST はサポートされていません。 システム ストップリストは、自動的に新しいフルテキスト インデックスに関連付けられます。

CREATE FULLTEXT STOPLIST、ALTER FULLTEXT STOPLIST、および DROP FULLTEXT STOPLIST はサポートされています。

MERGE は予約されたキーワードとして適用されません。

MERGE は完全に予約されたキーワードです。 MERGE ステートメントは、100 と 90 の両方の互換性レベルでサポートされます。

INSERT ステートメントの <dml_table_source> 引数を使用すると、構文エラーが発生します。

入れ子になった INSERT、UPDATE、DELETE、または MERGE ステートメント内の OUTPUT 句の結果をキャプチャして、対象のテーブルまたはビューに挿入することができます。 そのためには、INSERT ステートメントの <dml_table_source> 引数を使用します。

NOINDEX が指定されていない場合、DBCC CHECKDB または DBCC CHECKTABLE は、1 つのテーブルまたはインデックス付きビューとそのすべての非クラスター化インデックスおよび XML インデックスについて、物理的な一貫性と論理的な一貫性の両方をチェックします。 空間インデックスはサポートされません。

NOINDEX が指定されていない場合、DBCC CHECKDB または DBCC CHECKTABLE は、1 つのテーブルとそのすべての非クラスター化インデックスについて、物理的な一貫性と論理的な一貫性の両方をチェックします。 ただし、XML インデックス、空間インデックス、およびインデックス付きビューでは、既定で物理的な一貫性のみがチェックされます。

WITH EXTENDED_LOGICAL_CHECKS が指定されている場合、インデックス付きビュー、XML インデックス、および空間インデックス (存在する場合) に対して論理チェックが実行されます。 既定では、論理的な一貫性のチェック前に物理的な一貫性がチェックされます。 NOINDEX も指定されている場合は、論理チェックのみが実行されます。

データ操作言語 (DML) ステートメントで OUTPUT 句を使用した場合、ステートメントの実行時に実行時エラーが発生すると、トランザクション全体が終了し、ロールバックされます。

データ操作言語 (DML) ステートメントで OUTPUT 句を使用した場合、ステートメントの実行時に実行時エラーが発生したときの動作は、SET XACT_ABORT 設定によって異なります。 SET XACT_ABORT が OFF の場合は、OUTPUT 句を使用している DML ステートメントでステートメント中断エラーが発生すると、ステートメントは終了しますが、バッチの実行は続行され、トランザクションはロールバックされません。 SET XACT_ABORT が ON の場合は、OUTPUT 句を使用している DML ステートメントで実行時エラーが発生すると、バッチが終了し、トランザクションはロールバックされます。

CUBE および ROLLUP は予約されたキーワードとして適用されません。

CUBE および ROLLUP は、GROUP BY 句内では予約されたキーワードです。

XML の anyType 型の要素には厳密な検証が適用されます。

anyType 型の要素には緩やかな検証が適用されます。 詳細については、「ワイルドカード コンポーネントと内容検証」を参照してください。

特殊な属性 xsi:nil および xsi:type は、データ操作言語ステートメントでクエリまたは変更できません。

つまり、/e/@xsi:nil は失敗し、/e/@* では xsi:nil 属性と xsi:type 属性が無視されます。 ただし、xsi:nil = "false" の場合でも、/e では SELECT xmlCol との一貫性のために xsi:nil 属性と xsi:type 属性が返されます。

特殊な属性 xsi:nil および xsi:type は、標準属性として格納されるので、クエリも変更も可能です。

たとえば、クエリ SELECT x.query('a/b/@*') を実行すると、xsi:nil および xsi:type を含むすべての属性が返されます。 クエリでこれらの型を除外するには、@* を @*[namespace-uri(.) != "insert xsi namespace uri" に置き換え、(local-name(.) = "type" や local-name(.) ="nil". を避けてください。

XML 定数文字列値を SQL Server datetime 型に変換するユーザー定義関数は、"決定的" とマークされます。

XML 定数文字列値を SQL Server datetime 型に変換するユーザー定義関数は、"非決定的" とマークされます。

XML の union 型と list 型は、完全にはサポートされていません。

union 型と list 型は、完全にサポートされています (次の機能を含む)。

  • リストの和集合

  • 和集合の和集合

  • アトミック型のリスト

  • 和集合のリスト

xQuery メソッドに必要な SET オプションは、メソッドがビューまたはインライン テーブル値関数に含まれる場合に検証されません。

xQuery メソッドに必要な SET オプションは、メソッドがビューまたはインライン テーブル値関数に含まれる場合に検証されます。 メソッドの SET オプションが正しく設定されていない場合は、エラーが発生します。

行末文字 (復帰と改行) を含む XML 属性値は、XML 標準に従って正規化されません。 つまり、1 つの改行文字ではなく両方の文字が返されます。

行末文字 (復帰と改行) を含む XML 属性値は、XML 標準に従って正規化されます。 つまり、外部解析エンティティ (ドキュメント エンティティを含む) のすべての改行が、入力時に正規化されます。このとき、2 文字のシーケンス #xD #xA と、後ろに #xA がない #xD の両方について、1 つの #xA 文字に変換されます。

行末文字を含む文字列値を転送するための属性を使用しているアプリケーションは、このような文字が送信されても受け取りません。 正規化処理を回避するには、XML 数字エンティティを使用してすべての行末文字をエンコードしてください。

列プロパティ ROWGUIDCOL および IDENTITY は、制約として不適切に指定できます。 たとえば、ステートメント CREATE TABLE T (C1 int CONSTRAINT MyConstraint IDENTITY) は実行されますが、制約名は保持されず、ユーザーはその制約にアクセスできません。

列プロパティ ROWGUIDCOL および IDENTITY は、制約として指定できません。 エラー 156 が返されます。

UPDATE T1 SET @v = column_name = <expression> などの双方向の代入を使用して列を更新すると、予期しない結果が生じる可能性があります。これは、ステートメントの実行時に、WHERE 句や ON 句などの他の句でステートメントの開始値ではなく変数の有効期限の値を使用できるためです。 これにより、述語の意味が行ごとに予期せず変化することがあります。

この動作は、互換性レベルが 90 に設定されている場合にのみ適用されます。

双方向の代入を使用して列を更新すると、予想どおりの結果が生じます。これは、ステートメントの実行時に、列のステートメントの開始値のみが利用されるためです。

変数代入は、最上位レベルの UNION 演算子を含むステートメントで許可されていますが、予期しない結果が返されます。 たとえば、次のステートメントでは、2 つのテーブルの和集合からの列 BusinessEntityID の値がローカル変数 @v に割り当てられます。 定義上、SELECT ステートメントが複数の値を返した場合は、最後に返された値が変数に割り当てられます。 この場合は、最後の値が変数に正しく割り当てられますが、SELECT UNION ステートメントの結果セットも返されます。

ALTER DATABASE AdventureWorks2012
SET compatibility_level = 90;
GO
USE AdventureWorks2012;
GO
DECLARE @v int;
SELECT @v = BusinessEntityID FROM HumanResources.Employee
UNION ALL
SELECT @v = BusinessEntityID FROM HumanResources.EmployeeAddress;
SELECT @v;

変数代入は、最上位レベルの UNION 演算子を含むステートメントでは許可されていません。 エラー 10734 が返されます。

エラーを解決するには、次の例で示すようにクエリを書き直してください。

DECLARE @v int;
SELECT @v = BusinessEntityID FROM 
    (SELECT BusinessEntityID FROM HumanResources.Employee
     UNION ALL
     SELECT BusinessEntityID FROM HumanResources.EmployeeAddress) AS Test;
SELECT @v;

ODBC 関数 {fn CONVERT()} では、言語の既定の日付形式が使用されます。 言語によっては、既定の形式が YDM の場合があります。この場合、CONVERT() を {fn CURDATE()} などの YMD 形式が想定されている他の関数と組み合わせて使用すると、変換エラーが発生する可能性があります。

ODBC 関数 {fn CONVERT()} では、ODBC データ型 SQL_TIMESTAMP、SQL_DATE、SQL_TIME、SQLDATE、SQL_TYPE_TIME、および SQL_TYPE_TIMESTAMP への変換時にスタイル 121 (言語に依存しない YMD 形式) が使用されます。

ODBC 関数 {fn CURDATE()} では、'YYYY-MM-DD' 形式の日付のみが返されます。

ODBC 関数 {fn CURDATE()} では、日付と時刻の両方が返されます (YYYY-MM-DD hh:mm:ss など)。

DATEPART などの datetime 組み込み関数では、文字列入力値が有効な datetime リテラルである必要はありません。 たとえば、SELECT DATEPART (year, '2007/05-30') が正常にコンパイルされます。

DATEPART などの datetime 組み込み関数では、文字列入力値が有効な datetime リテラルである必要があります。 無効な datetime リテラルを使用すると、エラー 241 が返されます。

レベル 110 とより低い互換性レベルとの相違点

ここでは、互換性レベル 110 に導入された新しい動作について説明します。

互換性レベル設定 100 以下

互換性レベル設定 110

共通言語ランタイム (CLR) のデータベース オブジェクトは、CLR の Version 4 で実行されます。 ただし、CLR の Version 4 で導入されたいくつかの動作の変更が回避されます。 詳細については、「CLR 統合における新機能」を参照してください。

CLR のデータベース オブジェクトは、CLR の Version 4 で実行されます。

XQuery 関数の string-length および substring は、各サロゲートを 2 つの文字としてカウントします。

XQuery 関数の string-length および substring は、各サロゲートを 1 つの文字としてカウントします。

PIVOT は再帰共通テーブル式 (CTE) のクエリで許可されます。 ただし、グループごとに複数の行がある場合、クエリは誤った結果を返します。

PIVOT は再帰共通テーブル式 (CTE) のクエリで許可されません。 エラーが返されます。

RC4 アルゴリズムは、旧バージョンとの互換性のためにのみサポートされています。 データベース互換性レベルが 90 または 100 の場合、新しい素材は RC4 または RC4_128 を使用してのみ暗号化できます (非推奨)。SQL Server 2012 では、どの互換性レベルでも、RC4 または RC4_128 を使用して暗号化された素材を暗号化解除できます。

新素材は、RC4 または RC4_128 を使用して暗号化することはできません。 AES アルゴリズムのいずれかなど、新しいアルゴリズムを使用してください。 SQL Server 2012 では、どの互換性レベルでも、RC4 または RC4_128 を使用して暗号化された素材を暗号化解除できます。

time および datetime2 データ型に対する CAST および CONVERT 操作の既定のスタイルは、いずれかの型が計算列の式で使用されている場合を除き、121 です。 計算列の場合、既定のスタイルは 0 です。 この動作は、計算列が作成されるとき、自動パラメーター化を含むクエリで使用されるとき、または制約の定義で使用されるときに、計算列に影響を与えます。

次の例では、スタイル 0 と 121 の違いを示します。 上記の動作については示しません。 日付および時刻のスタイルの詳細については、「CAST および CONVERT (Transact-SQL)」を参照してください。

CREATE TABLE t1 (c1 time(7), c2 datetime2); 
INSERT t1 (c1,c2) VALUES (GETDATE(), GETDATE());
SELECT CONVERT(nvarchar(16),c1,0) AS TimeStyle0
       ,CONVERT(nvarchar(16),c1,121)AS TimeStyle121
       ,CONVERT(nvarchar(32),c2,0) AS Datetime2Style0
       ,CONVERT(nvarchar(32),c2,121)AS Datetime2Style121
FROM t1;
-- Returns values such as the following.
TimeStyle0       TimeStyle121     Datetime2Style0      Datetime2Style121
---------------- ---------------- -------------------- --------------------------
3:15PM           15:15:35.8100000 Jun  7 2011  3:15PM  2011-06-07 15:15:35.8130000

互換性レベル 110 では、time および datetime2 データ型に対する CAST および CONVERT 操作の既定のスタイルは常に 121 です。 クエリが古い動作に依存する場合は、110 より小さい互換性レベルを使用するか、または影響を受けるクエリで 0 スタイルを明示的に指定してください。

データベースを互換性レベル 110 にアップグレードしても、ディスクに格納されているユーザー データは変更されません。 このようなデータは手動で適切に修正する必要があります。 たとえば、SELECT INTO を使用して、前に説明した計算列の式を含むソースからテーブルを作成した場合は、計算列の定義自体ではなく、(スタイル 0 を使用する) データが格納されます。 このようなデータは、手動で更新してスタイル 121 に一致させる必要があります。

パーティション ビューで参照されるリモート テーブルの smalldatetime 型の列は、datetime としてマップされます。 ローカル テーブルの対応する列 (選択リストの同じ順番にある列) は、datetime 型であることが必要です。

パーティション ビューで参照されるリモート テーブルの smalldatetime 型の列は、smalldatetime としてマップされます。 ローカル テーブルの対応する列 (選択リストの同じ順番にある列) は、smalldatetime 型であることが必要です。

110 にアップグレードした後は、データ型の不一致により、分散パーティション ビューは失敗します。 この問題を解決するには、リモート テーブルでのデータ型を datetime に変更するか、またはローカル データベースの互換性レベルを 100 以下に設定します。

SOUNDEX 関数では次のルールが実装されます。

  1. SOUNDEX コードの同じ数値が割り当てられている 2 つの子音の間に大文字の H または大文字の W がある場合、この H または W は無視されます。

  2. character_expression の最初の 2 文字に SOUNDEX コードの同じ数値が割り当てられている場合は、両方の文字が含まれます。 最初の 2 文字の場合を除き、並んでいる一連の子音に SOUNDEX コードの同じ数値が割り当てられている場合、最初の文字以外はすべて除外されます。

SOUNDEX 関数では次のルールが実装されます。

  1. SOUNDEX コードの同じ数値が割り当てられている 2 つの子音の間に大文字の H または大文字の W がある場合、右側の子音は無視されます。

  2. 並んでいる一連の子音に SOUNDEX コードの同じ数値が割り当てられている場合、最初の文字以外はすべて除外されます。

その他のルールにより、SOUNDEX 関数で計算された値が、110 未満の互換性レベルで計算された値と異なる結果になる場合があります。 互換性レベル 110 へのアップグレード後に、SOUNDEX 関数を使用するインデックス、ヒープ、または CHECK 制約の再構築が必要になる場合があります。 詳細については、「SOUNDEX (Transact-SQL)」を参照してください。

予約済みキーワード

互換性設定では、データベース エンジンで予約されているキーワードも判別されます。 次の表は、各互換性レベルで使用される予約済みキーワードです。

互換性レベル設定

予約済みキーワード

110

WITHIN GROUP、TRY_CONVERT、SEMANTICKEYPHRASETABLE、SEMANTICSIMILARITYDETAILSTABLE、SEMANTICSIMILARITYTABLE

100

CUBE、MERGE、ROLLUP

90

EXTERNAL、PIVOT、UNPIVOT、REVERT、TABLESAMPLE

各互換性レベルの予約済みキーワードには、そのレベル以下で導入されるキーワードもすべて含まれています。 したがって、たとえばレベル 110 のアプリケーションの場合、上の表に一覧表示されているすべてのキーワードが予約されています。 それより下位の互換性レベルでは、レベル 100 のキーワードは有効なオブジェクト名ですが、そのキーワードに対応するレベル 110 の言語機能は使用できません。

キーワードはいったん導入されると、キーワードの予約が維持されます。 たとえば、互換性レベル 90 で導入された予約済みキーワード PIVOT は、レベル 100 と 110 でも予約済みとして扱われます。

互換性レベル設定でキーワードとして予約した識別子をアプリケーションで使用しようとすると、アプリケーションは失敗します。 この問題を回避するには、識別子をかっこ ([ ]) または引用符 (" ") で囲みます。たとえば、識別子 EXTERNAL を使用しているアプリケーションを互換性レベル 90 にアップグレードするには、識別子を [EXTERNAL] または "EXTERNAL" のように変更します。

詳細については、「予約済みキーワード (Transact-SQL)」を参照してください。

権限

データベースに対する ALTER 権限が必要です。

使用例

A. 互換性レベルを変更する

次の例では、 AdventureWorks2012 データベースの互換性レベルを 110, (SQL Server 2012) に変更します。

ALTER DATABASE AdventureWorks2012
SET COMPATIBILITY_LEVEL = 110;
GO

関連項目

参照

ALTER DATABASE (Transact-SQL)

予約済みキーワード (Transact-SQL)

CREATE DATABASE (Transact-SQL)

DATABASEPROPERTYEX (Transact-SQL)

sys.databases (Transact-SQL)

sys.database_files (Transact-SQL)