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

データベースの特定の動作を、指定したバージョンの SQL Server と互換性のある動作に設定します。SQL Server 2008 の新機能である次の ALTER DATABASE 構文は、sp_dbcmptlevel プロシージャに代わってデータベースの互換性レベルを設定します。その他の ALTER DATABASE オプションについては、「ALTER DATABASE (Transact-SQL)」を参照してください。

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

構文

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

引数

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

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

    80 = SQL Server 2000

    90 = SQL Server 2005

    100 = SQL Server 2008

説明

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

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

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

ベスト プラクティス

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

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

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

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

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

SET オプション

古い (低い) 互換性レベルでも新しい機能が動作する場合もありますが、SET オプションを使用するには調整が必要になることがあります。たとえば、互換性レベル 80 で xml データ型を使用すると、適切な ANSI SET オプションが必要になります。また、データベース互換性レベルが 90 以上に設定されている場合、ANSI_WARNINGS を ON に設定すると、暗黙的に ARITHABORT が ON に設定されます。データベース互換性レベルが 80 に設定されている場合は、ARITHABORT オプションを明示的に ON に設定する必要があります。詳細については、「結果に影響を与える SET オプション」を参照してください。

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

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

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

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

互換性レベル 90 では、動作が次のように変更されます。

互換性レベル設定 80

互換性レベル設定 90

影響度

FROM 句のロック ヒントに対して、WITH キーワードは常に省略可能です。

いくつかの例外を除き、テーブル ヒントは、FROM 句で WITH キーワードを使って指定した場合にのみサポートされます。詳細については、「FROM (Transact-SQL)」を参照してください。

警告メッセージでは、外部結合の演算子 *= および =* がサポートされます。

これらの演算子はサポートされません。OUTER JOIN キーワードを使用してください。

ORDER BY リストにある列参照を SELECT リスト内に定義されている列にバインドする場合、列のあいまいな部分は無視され、場合によっては列プレフィックスも無視されます。これにより、結果セットが予期しない順序で返されることがあります。

たとえば、ORDER BY 句に含まれる 1 つの列が 2 つの要素 (<table_alias>.<column>) で表され、この列が SELECT リストの中で列への参照として使用されている場合、ORDER BY 句は受け付けられますが、テーブルの別名は無視されます。次のクエリを考えてみます。

SELECT c1 = -c1 FROM t_table AS x ORDER BY x.c1

このクエリを実行するとき、ORDER BY で列のプレフィックスは無視されます。指定したソース列 (x.c1) に対しては期待どおりに並べ替え操作が行われず、代わりにクエリ内で定義されている派生列 c1 に対してソートが実行されます。このクエリの実行プランでは、まず派生列の値が計算され、次にその計算値が並べ替えられます。

列のあいまいな部分に関してエラーが発生します。ORDER BY 句に列のプレフィックスが指定されている場合、SELECT リストで定義されている列にバインドするときに、列のプレフィックスは無視されません。

次のクエリを考えてみます。

SELECT c1 = -c1 FROM t_table AS x ORDER BY x.c1

このクエリを実行するとき、ORDER BY 句内の列のプレフィックスは無視されません。指定したソース列 (x.c1) に対し、期待どおりに並べ替え操作が行われます。このクエリの実行プランでは、t_table から返された行を並べ替え操作で整列させた後、SELECT リストで定義されている派生列 c1 の値を計算するようになっています。

異なるデータ型に対する UNION の INSERT SELECT では、UNION の各分岐は、INSERT の対象列のデータ型に直接キャストされます。互換性のない型を変換したために自己結合が失敗したとしても、UNION の結果の型へのブランチが変換されることはないため、INSERT SELECT によって UNION が正常に行われます。

UNION の結果の型は INSERT SELECT とは無関係に派生します。UNION の各ブランチは UNION の結果の型にキャストされた後、INSERT の対象列の型にキャストされます。UNION に互換性のない型がある場合は、最初のキャストでエラーが発生する可能性があります。互換性レベル 90 で実行するには、INSERT SELECT 内で使用されている互換性のないデータ型の結合をすべて修正する必要があります。

WITH CHECK OPTION 句が指定されたビューを介して挿入操作と更新操作を実行しようとしても、そのビューまたは参照先のビューで TOP 句が使用されている場合、操作は適切にサポートされません。

WITH CHECK OPTION 句を使用するビューを介して挿入操作と更新操作を実行しようとしても、そのビューまたは参照先のビューで TOP 句が使用されている場合、操作はサポートされません。

可変長列と固定長列に UNION を実行すると、固定長列が生成されます。

可変長列と固定長列の UNION によって、可変長列が作成されます。

トリガ内で SET XACT_ABORT OFF が無視されます。このオプションは常に ON に設定されます。

トリガ内で SET XACT_ABORT を OFF に設定できます。

ビューで FOR BROWSE 句は許可されます (ただし無視されます)。

ビューで FOR BROWSE 句は許可されません。

ドメイン エラーは ANSI_WARNINGS で制御されません。ANSI_WARNINGS が OFF に設定されている場合は、ARITHABORT 設定が優先され、ARITHABORT に変更はありません。

ドメイン エラーは、ANSI_WARNINGS によっても制御される、重大度レベル 16 のエラーです。ANSI_WARNINGS または ARITHABORT が ON の場合は、NULL 値が返されるのではなく、エラーがスローされます。ARITHABORT が OFF に設定されていることを前提としているユーザー スクリプトは、この変更によって壊れる可能性があります。

リモート データ ソースに対してパススルー クエリ (OPENROWSET または OPENQUERY) を実行し、重複した名前の列が作成された場合、重複した列名は、クエリで明示的に列が指定されない限り無視されます。

リモート データ ソースに対するパススルー クエリ (OPENROWSET または OPENQUERY) が重複する名前を持つ列を作成する場合、エラーが発生します。

8,000 よりも大きいサイズの文字列定数と varbinary 定数は、text、ntext、または image として扱われます。

8,000 よりも大きいサイズの文字列定数は nvarchar(max)、varbinary 定数は varbinary(max)、あるいはどちらも varchar(max) の型として扱われます。これによって、SELECT リストにこのような式が含まれる場合は、SELECT ... INTO を使用して作成するテーブルのデータ型が変わる可能性があります。

数値型 (smallint、tinyint、int、bigint、numeric、decimal、smallmoney、money) どうしの比較は、データ型階層で優先順位が低い比較値を、優先順位が高い型に変換することによって行われます。

数値型の値は変換せずに比較されます。このため、パフォーマンスが向上します。ただし、変換によってオーバーフローの例外が発生する場合などは、動作が変わる可能性があります。

文字列引数をとる組み込みメタデータ関数は、入力が 4,000 文字より長い場合に入力が切り捨てられます。

組み込みメタデータ関数は、切り捨てによってスペース以外の文字が失われる場合にエラーが発生します。

引用符で囲まれていない識別子に許可されない文字セットがある場合は、変更されません。

Transact-SQL パーサーでは Unicode 3.2 規格がサポートされます。この規格ではいくつかの国際文字の文字分類が変更されており、区切られていない識別子では使用できない文字もあります。

浮動小数点ドメイン エラー (log() 関数に対する負の引数) が発生した場合、SET ANSI_WARNINGS ON の設定は SET ARITHABORT OFF の設定よりも優先されません。ANSI_WARNINGS が ON で ARITHABORT が OFF の場合、浮動小数点ドメイン エラーによってクエリが終了することはありません。

SET ANSI_WARNINGS ON は、ARITHABORT OFF 設定を完全に上書きします。この場合、浮動小数点ドメイン エラーが発生するとクエリが終了します。

ORDER BY 句で整数以外の定数を使用できます (無視されます)。

ORDER BY 句で整数以外の定数を使用できません。

(SET オプションが割り当てられていない) 空の SET ステートメントを使用できます。

空の SET 句は許可されません。

IDENTITY 属性は、派生テーブルによって作成された列に対して正しく派生されません。

IDENTITY 属性は、派生テーブルによって作成された列に対して正しく派生されます。

浮動小数点データ型に対する算術演算子の NULL 値許容プロパティは、常に NULL 値許容です。

浮動小数点データ型に対する算術演算子の NULL 値許容プロパティは、入力が NULL 値非許容であり、かつ ANSI_WARNINGS が ON の場合に NULL 値許容に変更されます。

UNION を使用する INSERT .. SELECT ステートメントでは、各結果セットによって作成される型がすべて挿入先の結果型に変換されます。

UNION を使用する INSERT .. SELECT ステートメントでは、各種ブランチの主要な型が決定され、結果がその型に変換された後、挿入先のテーブル型に変換されます。

SELECT ..FOR XML ステートメントでは、hex(27) (' 文字) と hex(22) (" 文字) が、必要ない場合でも常にエンティティ化されます。

FOR XML では、必要な場合のみ hex(27) と hex(22) がエンティティ化されます。次に示す状況ではエンティティ化されません。

  • 属性コンテンツでは、属性値が " で区切られる場合、hex(27) (' 文字) はエンティティ化されません。属性値が ' で区切られる場合、hex(22) (" 文字) はエンティティ化されません。

  • 要素コンテンツでは、hex(27) と hex(22) は一切エンティティ化されません。

FOR XML では、タイムスタンプ値が整数にマップされます。

FOR XML では、タイムスタンプ値はバイナリ値にマップされます。

詳細については、「timestamp データ型に対する FOR XML サポート」を参照してください。

高 (timestamp 列を使用する場合)、それ以外は低

FOR XML と OPENXML では、名前で使用される上位の Unicode 文字 (3 バイト) は 8 ビットで表されます。

たとえば、8 つの位置を使用して、FOR XML は Unicode コード ポイント U+10000 を次のように表します。

<a_x00010000_ c1="1" />

FOR XML と OPENXML では、名前に使用する高い範囲の Unicode 文字 (3 バイト) は 6 つの位置を使用して表します。

たとえば、6 つの位置を使用して、FOR XML は Unicode コード ポイント U+10000 を次のように表します。

<a_x010000_ c1="1" />

FOR XML では、AUTO モードでの派生テーブル マッピングは透過的に扱われます。

例 :

USE AdventureWorks
CREATE TABLE Test(id int);
INSERT INTO Test VALUES(1);
INSERT INTO Test VALUES(2);
SELECT * FROM (SELECT a.id AS a, 
b.id AS b FROM Test a 
JOIN Test b ON a.id=b.id) 
Test FOR XML AUTO;

AdventureWorks の互換性レベルが 80 に設定されている場合、上記の例は次のようになります。

<a a="1"><b b="1"/></a>

<a a="2"><b b="2"/></a>

FOR XML では、AUTO モードでの派生テーブル マッピングは不透過として扱われます。

AdventureWorks の互換性レベルを 90 に設定した場合、左記の例では次の結果が返されます。

<Test a="1" b="1"/>

<Test a="2" b="2"/>

高 (FOR XML AUTO モードがビューに適用される場合)、それ以外は低

文字列から money への変換では、日本語と韓国語でのみ、通貨記号としての円記号 (\) の使用がサポートされます。

すべての言語において、あらゆる文字列を money へ変換する場合にバックスラッシュ文字を使用できます。\ が通貨記号として使用されている場合、ISNUMERIC では true が返されます。

SQL Server 2005 より前のバージョンの SQL Server データベースでは、日本語と韓国語以外の言語の場合、バックスラッシュ文字を含む ISNUMERIC の戻り値に依存するインデックスと計算列は、この新しい動作によって分割されます。

オペランドで NULL 値が許容されず、ANSI_WARNINGS または ARITHABORT が ON に設定されている場合でも、算術演算子の結果では、常に NULL 値が許容されます。

ANSI_WARNINGS または ARITHABORT が ON に設定されているときは、両方のオペランドが NULL 値非許容の場合に浮動小数点算術演算子の結果が NULL 値を許容しません。

NULL 値許容がこのように変更されたため、SQL Server 2000 テーブルのバイナリ形式を使用するデータと一緒に浮動小数点算術演算子を使用する計算列を、bcp を使用して一括エクスポートし、bcp または BULK INSERT を使用してそのデータを同じ定義の SQL Server 2005 テーブルに一括インポートすると、エラーが発生する可能性があります。

注意注意
両方のオプションを OFF にした場合、結果はデータベース エンジンによって NULL 値を許容するものとしてマークされます。これは SQL Server 2000 と同じ動作です。

nvarchar をパラメータとして使用する組み込み関数では、渡された値が varchar の場合、値は nvarchar(4,000) に変換されます。SQL Server 2000 では、より大きい値が渡されると、その値は暗黙に切り捨てられます。

nvarchar をパラメータとしてとる組み込み関数に対しては、指定された値が varchar である場合、値はやはり nvarchar (4,000) に変換されます。ただし、より大きい値が渡されると、SQL Server 2008 ではエラーが発生します。

互換性レベル 90 で実行するには、切り捨ての動作によって影響を受けるカスタム コードを修正する必要があります。

固定長 (char、binary、または nchar) の文字列と可変長 (varchar、varbinary、nvarchar) の文字列を結合すると、固定長の結果が返されます。

可変サイズ文字列と固定サイズ文字列を結合すると、可変サイズ文字列が返されます。

互換性レベル 90 で実行するには、可変長型と固定長型の結合結果のデータ型に影響を受ける部分 (インデックス、クエリ、計算列) をすべて修正する必要があります。

文字 0xFFFF を含むオブジェクト名は、有効な識別子です。

文字 0xFFFF を含むオブジェクト名は無効な識別子であり、アクセスできません。

互換性レベル 90 で実行するには、この文字を含むオブジェクト名を変更する必要があります。

SELECT ISNUMERIC('<string>') の <string> に記述されるコンマは重要な意味があります。

たとえば、SELECT ISNUMERIC('121212,12') という次のクエリは 0 を返します。これは、文字列 121212,12 が数字ではないことを示します。

SELECT ISNUMERIC('<string>') の <string> に記述されるコンマは無視されます。

たとえば、SELECT ISNUMERIC('121212,12') という次のクエリは 1 を返します。これは、文字列 121212,12 が数字であることを示します。

Transact-SQL ステートメントの予約されたキーワードの後にコロン (:) がある場合、このコロンは無視されます。

Transact-SQL ステートメント内の予約キーワードに続くコロン (:) は、ステートメントが失敗する原因になります。

外部クエリからの列を参照するサブクエリの GROUP BY 句は正常に処理されます。

外部クエリからの列を参照するサブクエリの GROUP BY 句は、SQL 標準に従いエラーを返します。

レベル 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 属性値は、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 つのテーブルの和集合からの列 EmployeeID の値がローカル変数 @v に割り当てられます。定義上、SELECT ステートメントが複数の値を返した場合は、最後に返された値が変数に割り当てられます。この場合は、最後の値が変数に正しく割り当てられますが、SELECT UNION ステートメントの結果セットも返されます。

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

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

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

DECLARE @v int;
SELECT @v = EmployeeID FROM 
    (SELECT EmployeeID FROM HumanResources.Employee
     UNION ALL
     SELECT EmployeeID 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 が返されます。

予約済みキーワード

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

互換性レベル設定

予約済みキーワード

100

CUBE、MERGE、ROLLUP

90

EXTERNAL、PIVOT、UNPIVOT、REVERT、TABLESAMPLE

80

COLLATE、FUNCTION、OPENXML

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

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

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

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

権限

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

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

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

ALTER DATABASE AdventureWorks
SET COMPATIBILITY_LEVEL = 90;
GO

B. ORDER BY での互換性レベルの影響 (シナリオ 1)

次の例は、互換性レベル 80 と 100 の ORDER BY バインドの違いを示しています。この例では、サンプル テーブル SampleTable を tempdb データベース内に作成します。

USE tempdb;
CREATE TABLE SampleTable(c1 int, c2 int);
GO

互換性レベル 90 以上 (既定) の場合、次の SELECT... ORDER BY ステートメントを実行すると、AS 句の列の別名 c1 があいまいであるためエラーが発生します。

SELECT c1, c2 AS c1
FROM SampleTable
ORDER BY c1;
GO

データベースを互換性レベル 80 に再設定した後で、同じ SELECT... ORDER BY ステートメントを実行すると、ステートメントは成功します。

ALTER DATABASE tempdb
SET COMPATIBILITY_LEVEL = 80;
GO
SELECT c1, c2 AS c1
FROM SampleTable
ORDER BY c1;
GO

次の SELECT... ORDER BY ステートメントは、明確な別名が AS 句で指定されているため、どちらの互換性レベルでも機能します。

ALTER DATABASE tempdb
SET COMPATIBILITY_LEVEL = 100;
GO
SELECT c1, c2 AS c3
FROM SampleTable
ORDER BY c1;
GO

ALTER DATABASE tempdb
SET COMPATIBILITY_LEVEL = 80;
GO
SELECT c1, c2 AS c3
FROM SampleTable
ORDER BY c1;
GO

C. ORDER BY での互換性レベルの影響 (シナリオ 2)

互換性レベル 90 以上 (既定) の場合、次の SELECT...ORDER BY ステートメントを実行すると、ORDER BY 句で指定されている列の別名にテーブルのプレフィックスが含まれているためエラーが発生します。

SELECT c1 AS x
FROM SampleTable
ORDER BY SampleTable.x;
GO

データベースを互換性レベル 80 に再設定した後で、同じ SELECT...ORDER BY ステートメントを実行すると、ステートメントは成功します。

ALTER DATABASE tempdb
SET COMPATIBILITY_LEVEL = 80;
GO
SELECT c1 AS x
FROM SampleTable
ORDER BY SampleTable.x;
GO

次の SELECT...ORDER BY ステートメントは、ORDER BY 句で指定されている列の別名からテーブルのプレフィックスが削除されているため、どちらの互換性レベルでも機能します。

ALTER DATABASE tempdb
SET COMPATIBILITY_LEVEL = 100;
GO
SELECT c1 AS x
FROM SampleTable
ORDER BY x;
GO
ALTER DATABASE tempdb
SET COMPATIBILITY_LEVEL = 80;
GO
SELECT c1 AS x
FROM SampleTable
ORDER BY x;
GO

変更履歴

変更内容

XACT_ABORT ステートメントをトリガ内で指定した場合の動作を修正しました。トリガで XACT_ABORT を OFF に設定した場合、互換性レベル 80 では無視され、互換性レベル 90 以上では許可されます。前のドキュメントではこの情報が逆になっていました。