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 應用程式受到 SQL Server 2012 中行為差異的影響,請轉換應用程式,以便正常運作。 然後使用 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 是完整的保留關鍵字。 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 標準來正規化。 也就是說,外部剖析之實體 (包括文件實體) 內的所有分行符號都會在輸入上正規化,其方式是將雙字元序列 #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 運算子的陳述式中允許使用變數指派,但是會傳回非預期的結果。 例如在下列陳述式中,會將兩個資料表之聯集中的 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() 結合其他必須是 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。

低度

更低相容性層級和層級 110 之間的差異

本章節描述相容性層級 110 所導入的新行為。

相容性層級設定為 100 或更低

相容性層級設定為 110

Common Language Runtime (CLR) 資料庫物件是使用 CLR 4 版執行。 不過,CLR 4 版中導入的部分行為變更會加以忽略。 如需詳細資訊,請參閱<CLR 整合的新功能>。

CLR 資料庫物件是使用 CLR 4 版執行。

XQuery 函數 string-length 和 substring 會將每一個 Surrogate 計算為兩個字元。

XQuery 函數 string-length 和 substring 會將每一個 Surrogate 計為一個字元。

可以在遞迴通用資料表運算式 (CTE) 查詢中使用 PIVOT。 但每個分組如有多個資料列,查詢會傳回的結果將會不正確。

不可在遞迴通用資料表運算式 (CTE) 查詢中使用 PIVOT。 傳回錯誤。

只有 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. 如果大寫 H 或大寫 W 分隔擁有相同 SOUNDEX 代碼數字的兩個子音,則會忽略它們。

  2. 如果 character_expression 的前 2 個字元都有相同的 SOUNDEX 代碼數字,這兩個字元會包含在內。 否則,如果一組並存子音有相同的 SOUNDEX 代碼數字,除了第一個子音,所有子音都會被排除在外。

SOUNDEX 函數會實作以下規則:

  1. 如果大寫 H 或大寫 W 分隔擁有相同 SOUNDEX 代碼數字的兩個子音,則會忽略右邊的子音。

  2. 如果一組並存子音有相同的 SOUNDEX 代碼數字,除了第一個子音,所有子音都會被排除在外。

其他規則可能會使 SOUNDEX 函數計算的值不同於在舊版相容性層級下計算的值。 升級到相容性層級 110 之後,您可能需要重建使用 SOUNDEX 函數的索引、堆積或 CHECK 條件約束。 如需詳細資訊,請參閱<SOUNDEX (Transact-SQL)

保留關鍵字

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

相容性層級設定

保留關鍵字

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)