原生編譯的 T-SQL 模組支援的功能
適用於:SQL Server、Azure SQL 資料庫 和 Azure SQL 受控執行個體。
本主題包含原生編譯 T-SQL 模組主體的 T-SQL 介面區和支援功能的清單,如預存程序 (CREATE PROCEDURE (Transact-SQL))、純量使用者定義函數、內嵌資料表值的函數和觸發程序。
如需原生模組定義支援的功能,請參閱 原生編譯的預存程序上支援的建構。
如需有關不支援之建構的完整資訊,以及如何處理某些原生編譯模組不支援功能的相關資訊,請參閱 Migration Issues for Natively Compiled Stored Procedures。 如需不支援功能的詳細資訊,請參閱 記憶體中的 OLTP 不支援 Transact-SQL 建構。
原生模組中的查詢介面區
以下為支援的查詢結構:
CASE 運算式:CASE 可以用在允許有效運算式的任何陳述式或子句中。
- 適用於:SQL Server 2017 (14.x)。
自 SQL Server 2017 (14.x) 起,原生編譯 T-SQL 模組目前支援 CASE 陳述式。
SELECT 子句:
資料行和名稱別名 (使用 AS 或 = 語法)。
純量子查詢
- 適用於:SQL Server 2016 (13.x)。 自 SQL Server 2016 (13.x) 起,原生編譯模組現在支援純量子查詢。
回到頁首*
SELECT DISTINCT
適用於:SQL Server 2016 (13.x)。 自 SQL Server 2016 (13.x) 起,原生編譯模組支援 DISTINCT 運算子。
- 不支援相異彙總。
UNION 和 UNION ALL
- 適用於:SQL Server 2016 (13.x)。 自 SQL Server 2016 (13.x) 起,原生編譯模組目前支援 UNION 和 UNION ALL 運算子。
變數指派
FROM 子句:
FROM <記憶體最佳化的資料表或資料表變數>
FROM <原生編譯的內嵌 TVF>
LEFT OUTER JOIN、RIGHT OUTER JOIN、CROSS JOIN 和 INNER JOIN。
- 適用於:SQL Server 2016 (13.x)。 自 SQL Server 2016 (13.x) 起,原生編譯模組目前支援 JOINS。
子查詢
[AS] table_alias
。 如需詳細資訊,請參閱 FROM (Transact-SQL)。- 適用於:SQL Server 2016 (13.x)。 自 SQL Server 2016 (13.x) 起,原生編譯模組目前支援子查詢。
WHERE 子句:
篩選器述詞 IS [NOT] NULL
AND、BETWEEN
OR、NOT、IN、EXISTS
- 適用於:SQL Server 2016 (13.x)。 自 SQL Server 2016 (13.x) 起,原生編譯模組目前支援 OR/NOT/IN/EXISTS 運算子。
GROUP BY 子句:
彙總函數 AVG、COUNT、COUNT_BIG、MIN、MAX 和 SUM。
nvarchar、char、varchar、varchar、varbinary 和 binary 類型不支援 MIN 和 MAX。
ORDER BY 子句:
不支援 ORDER BY 子句中的 DISTINCT 。
若 GROUP BY 清單中逐字顯示 ORDER BY 清單中的運算式,則支援 GROUP BY (Transact-SQL)。
- 例如,支援 GROUP BY a + b ORDER BY a + b,但不支援 GROUP BY a, b ORDER BY a + b。
HAVING 子句:
- 和 WHERE 子句一樣的運算式限制。
原生編譯模組支援 ORDER BY 和 TOP,但有一些限制:
不支援 WITH TIES 子句中的 PERCENT 或 TOP 。
不支援 ORDER BY 子句中的 DISTINCT 。
在 TOP 子句中使用常數時,ORDER BY 與 TOP 結合不可大於 8,192。
- 如果查詢包含聯結或彙總函數,這個限制可能會降低。 (例如,如果有一個聯結 (兩個資料表),限制為 4,096 個資料列。 如果使用兩個聯結 (三個資料表),限制為 2,730 個資料列)。
- 您可以在變數中儲存資料列數,以取得大於 8,192 的結果。
DECLARE @v INT = 9000;
SELECT TOP (@v) ... FROM ... ORDER BY ...
不過,與使用變數相較, TOP 子句中的常數會產生較好的效能。
原生編譯 Transact-SQL 的這些限制不適用於記憶體最佳化資料表上解譯的 Transact-SQL 存取。
資料修改
以下為支援的 DML 陳述式。
INSERT VALUES (每個陳述式一個資料列) 和 INSERTSELECT
UPDATE
刪除
UPDATE 和 DELETE 陳述式支援 WHERE。
流程控制語言
支援下列的流程控制語言建構。
DECLARE @local_variable (Transact-SQL) 可使用所有支援的資料類型 (記憶體內部 OLTP),以及記憶體最佳化的資料表類型。 變數可以宣告為 NULL 或 NOT NULL。
-
- 若要最佳化效能,整個原生編譯 T-SQL 模組請使用單一 TRY/CATCH 區塊。
BEGIN ATOMIC (在預存程序的外部等級)。 如需詳細資訊,請參閱 Atomic Blocks。
支援的運算子
下列為支援的運算子。
比較運算子 (Transact-SQL) (例如 >、<、>= 和 <=)
一元運算子 (+、-)。
二元運算子 (*、/、+、-、% (模數) )。
- 數字和字串都支援加號運算子 (+)。
邏輯運算子 (AND、OR、NOT)。
位元運算子 ~、&、| 和 ^
APPLY 運算子
- 適用於:SQL Server 2017 (14.x)。
自 SQL Server 2017 (14.x) 起,原生編譯模組支援 APPLY 運算子。
- 適用於:SQL Server 2017 (14.x)。
原生編譯模組中的內建函數
記憶體最佳化資料表條件約束和原生編譯 T-SQL 模組支援下列函數。
日期函式:CURRENT_TIMESTAMP、DATEADD、DATEDIFF、DATEFROMPARTS、DATEPART、DATETIME2FROMPARTS、DATETIMEFROMPARTS、DAY、EOMONTH、GETDATE、GETUTCDATE、MONTH、SMALLDATETIMEFROMPARTS、SYSDATETIME、SYSUTCDATETIME 和 YEAR。
字串函式:LEN、LTRIM、RTRIM 和 SUBSTRING。
- 適用於:SQL Server 2017 (14.x)。
自 SQL Server 2017 (14.x) 起,同時支援下列內建函數︰TRIM、TRANSLATE 及 CONCAT_WS。
- 適用於:SQL Server 2017 (14.x)。
識別函式:SCOPE_IDENTITY
NULL 函式:ISNULL
Uniqueidentifier 函式:NEWID 和 NEWSEQUENTIALID
JSON 函數
- 適用於:SQL Server 2017 (14.x)。
自 SQL Server 2017 (14.x) 起,原生編譯模組支援 JSON 函數。
- 適用於:SQL Server 2017 (14.x)。
錯誤函式:ERROR_LINE、ERROR_MESSAGE、ERROR_NUMBER、ERROR_PROCEDURE、ERROR_SEVERITY 和 ERROR_STATE
系統函數:@@rowcount。 原生編譯預存程序內的陳述式會更新 @@rowcount,您可以在原生編譯預存程序中使用 @@rowcount,來判斷該原生編譯預存程序內最後執行之陳述式所影響的資料列數。 不過,@@rowcount 會在原生編譯預存程序開始及結束執行時重設為 0。
安全性函式:IS_MEMBER({'group' | 'role'})、IS_ROLEMEMBER ('role' [, 'database_principal'])、IS_SRVROLEMEMBER ('role' [, 'login'])、ORIGINAL_LOGIN()、SESSION_USER、CURRENT_USER、SUSER_ID(['login'])、SUSER_SID(['login'] [, Param2])、SUSER_SNAME([server_user_sid])、SYSTEM_USER、SUSER_NAME、USER、USER_ID(['user'])、USER_NAME([id])、CONTEXT_INFO()。
原生模組可以巢狀方式執行。
稽核
原生編譯預存程序中支援程序層級稽核。
如需有關稽核的詳細資訊,請參閱< 建立伺服器稽核和資料庫稽核規格>。
資料表和查詢提示
支援下列功能:
在資料表提示語法或查詢的 OPTION 子句 (Transact-SQL) 中的 INDEX、FORCESCAN 和 FORCESEEK 提示。 如需詳細資訊,請參閱資料表提示 (Transact-SQL)。
FORCE ORDER
LOOP 聯結提示
OPTIMIZE FOR
如需詳細資訊,請參閱 查詢提示 (Transact-SQL)。
排序的限制
在使用 TOP (Transact-SQL) 和一個 ORDER BY 子句 (Transact-SQL) 的查詢中,您可排序 8000 多個資料列。 然而,若沒有 ORDER BY 子句 (Transact-SQL),TOP (Transact-SQL) 最多只能排序 8000 個資料列 (如有聯結則資料列更少)。
若查詢同時使用 TOP (Transact-SQL) 運算子和一個 ORDER BY 子句 (Transact-SQL),則 TOP 運算子最多可指定 8192 個資料列。 若您指定超過 8192 個資料列,則會收到錯誤訊息:Msg 41398,層級 16,狀態 1、程序 <procedureName>、行 <lineNumber>。TOP 運算子最多可以傳回 8192 個資料列;已要求 <number>。
如果您沒有 TOP 子句,則可以使用 ORDER BY 排序任意數目的資料列。
如果您未使用 ORDER BY 子句,則可以使用任何整數值搭配 TOP 運算子。
使用 TOP N = 8192 的範例:編譯
CREATE PROCEDURE testTop
WITH EXECUTE AS OWNER, SCHEMABINDING, NATIVE_COMPILATION
AS
BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')
SELECT TOP 8192 ShoppingCartId, CreatedDate, TotalPrice FROM dbo.ShoppingCart
ORDER BY ShoppingCartId DESC
END;
GO
TOP N > 8192 的範例:編譯失敗。
CREATE PROCEDURE testTop
WITH EXECUTE AS OWNER, SCHEMABINDING, NATIVE_COMPILATION
AS
BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')
SELECT TOP 8193 ShoppingCartId, CreatedDate, TotalPrice FROM dbo.ShoppingCart
ORDER BY ShoppingCartId DESC
END;
GO
8192 資料列限制只適用於 TOP N
,其中 N
是常數,如前面的範例中所示。 如果您需要讓 N
大於 8192,可以將值指派給變數,並使用該變數搭配 TOP
。
使用變數的範例:編譯
CREATE PROCEDURE testTop
WITH EXECUTE AS OWNER, SCHEMABINDING, NATIVE_COMPILATION
AS
BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')
DECLARE @v int = 8193
SELECT TOP (@v) ShoppingCartId, CreatedDate, TotalPrice FROM dbo.ShoppingCart
ORDER BY ShoppingCartId DESC
END;
GO
傳回資料列的限制: 有兩種情況可能會減少 TOP 運算子能夠傳回的資料列數目:
在查詢中使用 JOIN。 JOIN 對限制的影響取決於查詢計劃。
使用彙總函式或參考彙總 ORDER BY 子句中的函式。
計算 TOP N 中最差情況下支援之最大值 N 的公式是: N = floor ( 65536 / number_of_tables * 8 + total_size+of+aggs )
。