ALTER DATABASE 相容性層級 (Transact-SQL)

設定要相容於指定 SQL Server 版本的特定資料庫行為。下列 ALTER DATABASE 語法是 SQL Server 2008 中的新增功能,將取代 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 應用程式受到 SQL Server 2008 中行為差異的影響,請轉換應用程式,以便正常運作。然後使用 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 關鍵字一律是選擇性的。

但有某些例外,僅當利用 WITH 關鍵字指定提示時,FROM 子句才會支援資料表提示。如需詳細資訊,請參閱<FROM (Transact-SQL)>。

支援外部聯結的 *= 和 =* 運算子,使用警告訊息。

不支援這些運算子;應該使用 OUTER JOIN 關鍵字。

WHEN 會將 ORDER BY 清單中的資料行參考繫結至 SELECT 清單中定義的資料行,模稜兩可的資料行會被忽略,有時也會忽略資料行前置詞。這可能導致結果集以非預期的順序傳回。

例如,會接受由單一兩部分資料行 (<table_alias>.<column>) 所組成的 ORDER BY 子句 (該資料行是用來當做 SELECT 清單中之資料行的參考),但資料表別名會被忽略。請看下列查詢。

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 目的地資料行的類型。即使本身使用的聯集會因類型轉換不相容而失敗,INSERT SELECT 也會使 UNION 成功,因為 UNION 結果類型的分支永遠不會轉換。

UNION 結果類型的衍生與 INSERT SELECT 無關。UNION 的每個分支都會轉換成 UNION 的結果類型,之後再轉換成 INSERT 的目標資料行類型。如果 UNION 中有不相容的類型,第一個轉換可能造成錯誤。若要執行相容性層級 90,您必須先修復 INSERT SELECT 內所用的所有不相容的類型聯集。

透過檢視表執行的插入及更新作業,將會在該檢視表或參考的檢視表使用 TOP 子句時,不正確地在指定 WITH CHECK OPTION 子句的檢視表上受到支援。

透過檢視表執行的插入及更新作業,將會在該檢視表或參考的檢視表使用 TOP 子句時,不受到使用 WITH CHECK OPTION 的檢視表所支援。

可變長度資料行和固定長度資料行的 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 值。相依於設為 OFF 之 ARITHABORT 的使用者指令碼,可能會因這項變更而中斷。

如果針對遠端資料來源 [OPENROWSET 或 OPENQUERY] 執行的傳遞查詢產生名稱重複的資料行,除非查詢中明確地命名資料行,否則,系統會忽略重複的資料行名稱。

如果針對遠端資料來源 [OPENROWSET 或 OPENQUERY] 執行的傳遞查詢產生含有重複資料行名稱的資料行,便會發生錯誤。

大小超出 8000 的字元字串常數和 varbinary 常數會當做 text、ntext 或 image 來處理。

大小超出 8000 的字元字串常數和 varbinary 常數會當做 varchar(max) 類型 (或分別為 nvarchar(max) 和 varbinary(max)) 來處理。如果 SELECT 清單包含這類運算式,如此便可以變更利用 SELECT … INTO 所建立的資料表之資料類型。

藉由將類型階層中優先順序較低的比較元轉換成優先順序較高的類型來進行數值類型 (smallint、tinyint、int、bigint、numeric、decimal、smallmoney、money) 的比較。

數值類型的值,不進行轉換,直接比較。這可增進效能。不過,這可能改變某些行為,當轉換會造成溢位例外狀況時,尤其如此。

如果輸入長度超出 4000 個字元,採用字串引數的內建中繼資料函數會截斷其輸入。

如果這項截斷作業會造成非空白字元遺失,內建中繼資料函數便會發生錯誤。

不含引號的識別碼中所不允許使用的字元集,仍保持不變。

Transact-SQL 剖析器支援 Unicode 3.2 標準,它變更了非分隔識別碼中目前不允許使用的某些國際字元的字元分類。

在浮點網域錯誤的狀況下,SET ANSI_WARNINGS ON 不會覆寫 SET ARITHABORT OFF 的設定 [也就是說,log() 函數的負值引數]。如果 ANSI_WARNINGS 是 ON,但 ARITHABORT 是 OFF,浮點網域錯誤並不會使查詢終止。

SET ANSI_WARNINGS ON 會完整覆寫 ARITHABORT OFF 設定。這種狀況的浮點網域錯誤會使查詢終止。

在 ORDER BY 子句中,允許 (但會忽略) 非整數常數。

在 ORDER BY 子句中,不允許非整數常數。

允許空白 SET 陳述式 (未指派 SET 選項)。

不允許空白 SET 子句。

沒有針對衍生資料表所產生的資料行,正確衍生出 IDENTITY 屬性。

針對衍生資料表所產生的資料行,正確衍生出 IDENTITY 屬性。

浮點資料類型算術運算子的 Null 屬性永遠可為 Null。

在輸入不可為 Null 且 ANSI_WARNINGS 為 ON 的狀況下,浮點資料類型算術運算子的 Null 屬性改成不可為 Null。

在 INSERT ..SELECT 陳述式 (包含 UNION) 中,個別結果集產生的類型會全部轉換成目標結果類型。

在 INSERT ..SELECT 陳述式 (包含 UNION) 中,各個分支的主要類型已確定,結果在轉換成目標資料表類型之前,會先轉換成這個類型。

在 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 中,用 8 個位置來表示名稱中的高範圍 Unicode 字元 (3 個位元組)。

例如,當使用 8 個位置時,FOR XML 會用下列方式來表示 Unicode 字碼指標 U+10000:

<a_x00010000_ c1="1" />

在 FOR XML 和 OPENXML 中,用 6 個位置來表示名稱中的高範圍 Unicode 字元 (3 個位元組)。

例如,當使用 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,即使運算元不可為 Null 且 ANSI_WARNINGS 或 ARITHABORT 設定為 ON,也是如此。

當 ANSI_WARNINGS 或 ARITHABORT 設為 ON 時,如果兩個運算元都不可為 Null,浮點算術運算子的結果便不可為 Null。

當使用 bcp,從含有計算資料行 (使用符點算術運算元) 的 SQL Server 2000 資料表中大量匯出二進位格式資料,再使用 bcp 或 BULK INSERT,將這項資料大量匯入到含有相同定義的 SQL Server 2005 資料表時,這項 Null 屬性的變更便會失敗。

附註附註
當兩個選項都是 OFF 時,Database Engine 會將結果標示為可為 Null。這與 SQL Server 2000 相同。

對於採用 nvarchar 做為參數的內建函數,如果提供的值是 varchar,這個值會轉換成 nvarchar(4000)。在 SQL Server 2000 中,如果傳送較大的值,會以無訊息的方式來截斷這個值。

對於採用 nvarchar 做為參數的內建函數,如果提供的值是 varchar,這個值仍會轉換成 nvarchar(4000)。不過,如果傳送較大的值,SQL Server 2008 會產生錯誤。

若要執行相容性層級 90,您必須先修復會依賴截斷行為的任何自訂程式碼。

含有可變長度 (varchar、varbinary、nvarchar) 字串的固定長度 (char、binary 或 nchar) 字串的聯集,會傳回固定長度結果。

可變大小字串和固定大小字串的聯集,會傳回可變大小的字串。

若要在相容性層級 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 是完整的保留關鍵字。100 和 90 相容性層級之下都有支援 MERGE 陳述式。

使用 INSERT 陳述式的 <dml_table_source> 引數會引發語法錯誤。

您可以在巢狀 INSERT、UPDATE、DELETE 或 MERGE 陳述式中擷取 OUTPUT 子句的結果,並將這些結果插入目標資料表或檢視表中。這是利用 INSERT 陳述式中的 <dml_table_source> 引數所完成。

除非指定了 NOINDEX,否則 DBCC CHECKDB 或 DBCC CHECKTABLE 會針對單一資料表或索引檢視表及它的所有非叢集索引和 XML 索引進行實體和邏輯一致性檢查。不支援空間索引。

除非指定了 NOINDEX,否則 DBCC CHECKDB 或 DBCC CHECKTABLE 會針對單一資料表及它的所有非叢集索引進行實體和邏輯一致性檢查。但是根據預設,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 子句中為保留關鍵字。

Strict 驗證會套用到 XML anyType 類型的元素。

Lax 驗證會套用到 anyType 類型的元素。如需詳細資訊,請參閱<萬用字元元件和內容驗證>。

資料操作語言陳述式無法查詢或修改特殊屬性 xsi:nilxsi:type

這表示當 /e/@* 忽略 xsi:nil 和 xsi:type 屬性時,/e/@xsi:nil 會失敗。但是,/e 會傳回 xsi:nil 和 xsi:type 屬性以便與 SELECT xmlCol 一致,即使 xsi:nil = "false" 也是如此。

特殊屬性 xsi:nilxsi:type 會儲存為一般屬性,而且可進行查詢和修改。

例如,執行 SELECT x.query('a/b/@*') 查詢會傳回所有屬性,包括 xsi:nilxsi:type。若要在查詢中排除這些類型,請將 @* 取代為 @*[namespace-uri(.) != "insert xsi namespace uri",而非 (local-name(.) = "type" 或 local-name(.) ="nil".

將 XML 常數字串值轉換成 SQL Server 日期時間類型的使用者定義函數會標示為決定性。

將 XML 常數字串值轉換成 SQL Server 日期時間類型的使用者定義函數會標示為不具決定性。

XML 聯集和清單類型並未受到完整支援。

聯集和清單類型受到完整支援,包括以下功能:

  • 清單的聯集

  • 聯集的聯集

  • 不可部分完成之類型的清單

  • 聯集的清單

當此方法包含在檢視表或是內嵌資料表值函數內時,不會驗證 xQuery 方法所需的 SET 選項。

當此方法包含在檢視表或是內嵌資料表值函數內時,將會驗證 xQuery 方法所需的 SET 選項。如果未能正確設定此方法的 SET 選項,將會引發錯誤。

如需有關必要選項設定的詳細資訊,請參閱<設定選項 (XML 資料類型)>。

包含行尾字元 (歸位字元和換行字元) 的 XML 屬性值不會根據 XML 標準來正規化。也就是說,會傳回這兩個字元,而不是單一換行字元。

包含行尾字元 (歸位字元和換行字元) 的 XML 屬性值會根據 XML 標準來正規化。也就是說,外部剖析之實體 (包括文件實體) 內的所有分行符號都會在輸入上正規化,其方式是將雙字元序列 #xD #xA 及任何緊接著 #xA 的 #xD 轉換成單一 #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 運算子的陳述式中允許使用變數指派,但是會傳回非預期的結果。例如在下列陳述式中,會將兩個資料表之聯集中的 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() 結合其他必須是 YMD 格式的函數 (例如 {fn CURDATE()}) 使用時產生轉換錯誤。

當 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) 不會要求字串輸入值必須是有效的日期時間常值。例如,SELECT DATEPART (year, '2007/05-30') 會編譯成功。

日期時間內建 (如 DATEPART) 會要求字串輸入值必須是有效的日期時間常值。當使用無效的日期時間常值時會傳回錯誤 241。

保留關鍵字

相容性設定也決定了 Database Engine 所保留的關鍵字。下表顯示每個相容性層級所導入的保留關鍵字。

相容性層級設定

保留關鍵字

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 繫結中的差異。這個範例會在 tempdb 資料庫中建立範例資料表 SampleTable。

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 陳述式的行為。在 80 相容性層級中,系統會忽略在觸發程序內,將 XACT_ABORT 設定為 OFF 的設定。不過,在 90 和更高的相容性層級中,則允許使用這種設定。先前的文件反轉了這項資訊。