原生編譯的 T-SQL 模組支援的功能

適用於:SQL ServerAzure SQL DatabaseAzure 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 子句中的 PERCENTTOP

  • 不支援 ORDER BY 子句中的 DISTINCT

  • TOP 子句中使用常數時,ORDER BYTOP 結合不可大於 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。

流程控制語言

支援下列的流程控制語言建構。

支援的運算子

下列為支援的運算子。

  • 比較運算子 (Transact-SQL) (例如 >、<、>= 和 <=)

  • 一元運算子 (+、-)。

  • 二元運算子 (*、/、+、-、% (模數) )。

    • 數字和字串都支援加號運算子 (+)。
  • 邏輯運算子 (AND、OR、NOT)。

  • 位元運算子 ~、&、| 和 ^

  • APPLY 運算子

    • 適用於:SQL Server 2017 (14.x)。
      自 SQL Server 2017 (14.x) 起,原生編譯模組支援 APPLY 運算子。

原生編譯模組中的內建函數

記憶體最佳化資料表條件約束和原生編譯 T-SQL 模組支援下列函數。

  • 所有數學函數 (Transact-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。
  • 識別函式:SCOPE_IDENTITY

  • NULL 函式:ISNULL

  • Uniqueidentifier 函式:NEWID 和 NEWSEQUENTIALID

  • JSON 函數

    • 適用於:SQL Server 2017 (14.x)。
      自 SQL Server 2017 (14.x) 起,原生編譯模組支援 JSON 函數。
  • 錯誤函式: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()。

  • 原生模組可以巢狀方式執行。

稽核

原生編譯預存程序中支援程序層級稽核。

如需有關稽核的詳細資訊,請參閱< 建立伺服器稽核和資料庫稽核規格>。

資料表和查詢提示

支援下列功能:

如需詳細資訊,請參閱 查詢提示 (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 )

另請參閱

原生編譯的預存程序
原生編譯預存程序的移轉問題