適用於 Functions 的 Azure SQL 觸發程式
Azure SQL 觸發程式會使用 SQL 變更追蹤 功能來監視 SQL 資料表的變更,並在建立、更新或刪除資料列時觸發函式。 如需變更追蹤與 Azure SQL 觸發程式搭配使用的組態詳細數據,請參閱 設定變更追蹤。 如需 Azure Functions 的 Azure SQL 擴充功能設定詳細數據的詳細資訊,請參閱 SQL 系結概觀。
Azure SQL 觸發程式的使用量和進階方案調整決策是透過以目標為基礎的調整來完成。 如需詳細資訊,請參閱 以目標為基礎的調整。
功能概觀
Azure SQL 觸發程式系結會使用輪詢循環來檢查變更,在偵測到變更時觸發使用者函式。 概括而言,迴圈看起來像這樣:
while (true) {
1. Get list of changes on table - up to a maximum number controlled by the Sql_Trigger_MaxBatchSize setting
2. Trigger function with list of changes
3. Wait for delay controlled by Sql_Trigger_PollingIntervalMs setting
}
變更會依照變更的順序進行處理,並先處理最舊的變更。 關於變更處理的幾個注意事項:
- 如果同時對多個數據列所做的變更,則會根據 CHANGETABLE 函式傳回的順序,以傳送至函式的確切順序為基礎
- 數據列的變更會「批處理」在一起。 如果在迴圈的每個反覆項目之間對某個數據列進行多個變更,則該數據列只會有單一變更專案,而該數據列會顯示上次處理狀態與目前狀態之間的差異
- 如果對一組數據列進行變更,然後對相同數據列的一半進行另一組變更,則會先處理第二次未變更的一半數據列。 此處理邏輯是由於上述附註與正在批處理的變更 - 觸發程式只會看到進行「最後」變更,並針對處理它們的順序使用
如需變更追蹤及其由 Azure SQL 觸發程式等應用程式使用方式的詳細資訊,請參閱 使用變更追蹤 。
範例使用方式
在 GitHub 存放庫中可取得 Azure SQL 觸發程序的其他範例。
這些範例會參考 ToDoItem
類別和對應的資料庫資料表:
namespace AzureSQL.ToDo
{
public class ToDoItem
{
public Guid Id { get; set; }
public int? order { get; set; }
public string title { get; set; }
public string url { get; set; }
public bool? completed { get; set; }
}
}
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
資料庫和資料表上已啟用變更追蹤:
ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;
SQL 觸發程序會繫結至 IReadOnlyList<SqlChange<T>>
,這是各有兩個屬性的 SqlChange
物件清單:
- 項目:已變更的項目。 項目的類型應遵循
ToDoItem
類別中所見的資料表結構描述。 - 作業:
SqlChangeOperation
列舉中的值。 可能的值為:Insert
、Update
和Delete
。
下列範例顯示當資料表有變更時所叫用的 ToDo
C# 函式:
using System;
using System.Collections.Generic;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Sql;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace AzureSQL.ToDo
{
public static class ToDoTrigger
{
[Function("ToDoTrigger")]
public static void Run(
[SqlTrigger("[dbo].[ToDo]", "SqlConnectionString")]
IReadOnlyList<SqlChange<ToDoItem>> changes,
FunctionContext context)
{
var logger = context.GetLogger("ToDoTrigger");
foreach (SqlChange<ToDoItem> change in changes)
{
ToDoItem toDoItem = change.Item;
logger.LogInformation($"Change operation: {change.Operation}");
logger.LogInformation($"Id: {toDoItem.Id}, Title: {toDoItem.title}, Url: {toDoItem.url}, Completed: {toDoItem.completed}");
}
}
}
}
範例使用方式
在 GitHub 存放庫中可取得 Azure SQL 觸發程序的其他範例。
此範例會參考類別 ToDoItem
、類別 SqlChangeToDoItem
、 SqlChangeOperation
列舉和對應的資料庫資料表:
在不同的檔案 ToDoItem.java
中:
package com.function;
import java.util.UUID;
public class ToDoItem {
public UUID Id;
public int order;
public String title;
public String url;
public boolean completed;
public ToDoItem() {
}
public ToDoItem(UUID Id, int order, String title, String url, boolean completed) {
this.Id = Id;
this.order = order;
this.title = title;
this.url = url;
this.completed = completed;
}
}
在不同的檔案 SqlChangeToDoItem.java
中:
package com.function;
public class SqlChangeToDoItem {
public ToDoItem item;
public SqlChangeOperation operation;
public SqlChangeToDoItem() {
}
public SqlChangeToDoItem(ToDoItem Item, SqlChangeOperation Operation) {
this.Item = Item;
this.Operation = Operation;
}
}
在不同的檔案 SqlChangeOperation.java
中:
package com.function;
import com.google.gson.annotations.SerializedName;
public enum SqlChangeOperation {
@SerializedName("0")
Insert,
@SerializedName("1")
Update,
@SerializedName("2")
Delete;
}
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
資料庫和資料表上已啟用變更追蹤:
ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;
SQL 觸發程式會系結至 SqlChangeToDoItem[]
,每個物件陣列 SqlChangeToDoItem
都有兩個屬性:
- item: 已變更的專案。 項目的類型應遵循
ToDoItem
類別中所見的資料表結構描述。 - operation: 列舉
SqlChangeOperation
的值。 可能的值為:Insert
、Update
和Delete
。
下列範例顯示當資料表有變更時叫用的 ToDo
Java 函式:
package com.function;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.sql.annotation.SQLTrigger;
import com.function.Common.SqlChangeToDoItem;
import com.google.gson.Gson;
import java.util.logging.Level;
public class ProductsTrigger {
@FunctionName("ToDoTrigger")
public void run(
@SQLTrigger(
name = "todoItems",
tableName = "[dbo].[ToDo]",
connectionStringSetting = "SqlConnectionString")
SqlChangeToDoItem[] todoItems,
ExecutionContext context) {
context.getLogger().log(Level.INFO, "SQL Changes: " + new Gson().toJson(changes));
}
}
範例使用方式
在 GitHub 存放庫中可取得 Azure SQL 觸發程序的其他範例。
此範例會參考 ToDoItem
資料庫資料表:
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
資料庫和資料表上已啟用變更追蹤:
ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;
SQL 觸發程式會系結至 todoChanges
,其中各有兩個屬性的物件清單:
- item: 已變更的專案。 項目的結構會遵循數據表架構。
- operation: 可能的值為
Insert
、Update
和Delete
。
下列範例顯示當數據表有變更時叫用的 ToDo
PowerShell 函式。
以下是 function.json 檔案中的繫結資料:
{
"name": "todoChanges",
"type": "sqlTrigger",
"direction": "in",
"tableName": "dbo.ToDo",
"connectionStringSetting": "SqlConnectionString"
}
組 態 區段說明這些屬性。
以下是 檔案中函式的 run.ps1
範例 PowerShell 程式代碼:
using namespace System.Net
param($todoChanges)
# The output is used to inspect the trigger binding parameter in test methods.
# Use -Compress to remove new lines and spaces for testing purposes.
$changesJson = $todoChanges | ConvertTo-Json -Compress
Write-Host "SQL Changes: $changesJson"
範例使用方式
在 GitHub 存放庫中可取得 Azure SQL 觸發程序的其他範例。
此範例會參考 ToDoItem
資料庫資料表:
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
資料庫和資料表上已啟用變更追蹤:
ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;
SQL 觸發程式會 todoChanges
系結 ,每個物件陣列都有兩個屬性:
- item: 已變更的專案。 項目的結構會遵循數據表架構。
- operation: 可能的值為
Insert
、Update
和Delete
。
下列範例顯示當數據表有變更時所叫用的 ToDo
JavaScript 函式。
以下是 function.json 檔案中的繫結資料:
{
"name": "todoChanges",
"type": "sqlTrigger",
"direction": "in",
"tableName": "dbo.ToDo",
"connectionStringSetting": "SqlConnectionString"
}
組 態 區段說明這些屬性。
以下是 檔案中函式的 index.js
JavaScript 程式代碼範例:
module.exports = async function (context, todoChanges) {
context.log(`SQL Changes: ${JSON.stringify(todoChanges)}`)
}
範例使用方式
在 GitHub 存放庫中可取得 Azure SQL 觸發程序的其他範例。
此範例會參考 ToDoItem
資料庫資料表:
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
資料庫和資料表上已啟用變更追蹤:
ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;
SQL 觸發程式會系結至變數 todoChanges
,每個物件清單各有兩個屬性:
- item: 已變更的專案。 項目的結構會遵循數據表架構。
- operation: 可能的值為
Insert
、Update
和Delete
。
下列範例顯示當數據表有變更時叫用的 ToDo
Python 函式。
以下是 function_app.py 檔案的 Python 程式代碼範例:
import json
import logging
import azure.functions as func
from azure.functions.decorators.core import DataType
app = func.FunctionApp()
@app.function_name(name="ToDoTrigger")
@app.sql_trigger(arg_name="todo",
table_name="ToDo",
connection_string_setting="SqlConnectionString")
def todo_trigger(todo: str) -> None:
logging.info("SQL Changes: %s", json.loads(todo))
屬性
C# 連結 庫 會使用 SqlTrigger 屬性在函式上宣告 SQL 觸發程式,其具有下列屬性:
屬性內容 | 描述 |
---|---|
TableName | 必要。 觸發程式所監視之數據表的名稱。 |
ConnectionStringSetting | 必要。 包含資料庫 連接字串 的應用程式設定名稱,其中包含受監視變更之數據表的資料庫。 連接字串 設定名稱會對應至包含 Azure SQL 或 SQL Server 實例 連接字串 的應用程式設定(用於local.settings.json 本機開發)。 |
LeasesTableName | 選擇性。 用來儲存租用的數據表名稱。 如果未指定,租用數據表名稱將會Leases_{FunctionId}_{TableId}。 如需如何產生此項目的詳細資訊,請參閱 這裡。 |
註釋
在 Java 函式運行時間連結庫中,對值來自 Azure SQL 的參數使用 @SQLTrigger
註釋 (com.microsoft.azure.functions.sql.annotation.SQLTrigger
)。 此批註支援下列元素:
元素 | 描述 |
---|---|
name | 必要。 觸發程式系結至的參數名稱。 |
tableName | 必要。 觸發程式所監視之數據表的名稱。 |
connectionStringSetting | 必要。 包含資料庫 連接字串 的應用程式設定名稱,其中包含受監視變更之數據表的資料庫。 連接字串 設定名稱會對應至包含 Azure SQL 或 SQL Server 實例 連接字串 的應用程式設定(用於local.settings.json 本機開發)。 |
LeasesTableName | 選擇性。 用來儲存租用的數據表名稱。 如果未指定,租用數據表名稱將會Leases_{FunctionId}_{TableId}。 如需如何產生此項目的詳細資訊,請參閱 這裡。 |
組態
下表說明您在 function.json 檔案中設定的繫結設定屬性。
function.json 屬性 | 描述 |
---|---|
name | 必要。 觸發程式系結至的參數名稱。 |
type | 必要。 必須設定為 sqlTrigger 。 |
direction | 必要。 必須設定為 in 。 |
tableName | 必要。 觸發程式所監視之數據表的名稱。 |
connectionStringSetting | 必要。 包含資料庫 連接字串 的應用程式設定名稱,其中包含監視變更的數據表。 連接字串 設定名稱會對應至包含 Azure SQL 或 SQL Server 實例 連接字串 的應用程式設定(用於local.settings.json 本機開發)。 |
LeasesTableName | 選擇性。 用來儲存租用的數據表名稱。 如果未指定,租用數據表名稱將會Leases_{FunctionId}_{TableId}。 如需如何產生此項目的詳細資訊,請參閱 這裡。 |
選用設定
您可以針對本機開發或雲端部署的 SQL 觸發程式設定下列選擇性設定。
host.json
本節說明 2.x 版和更新版本中此系結可用的組態設定。 host.json檔案中的設定會套用至函式應用程式實例中的所有函式。 下列範例host.json檔案只包含此系結的 2.x+ 版設定。 如需 2.x 版和更新版本中函式應用程式組態設定的詳細資訊,請參閱 Azure Functions 的host.json參考。
設定 | 預設 | 描述 |
---|---|---|
MaxBatchSize | 100 | 傳送至觸發程式函式之前,每個觸發程式循環反覆專案所處理的變更數目上限。 |
PollingIntervalMs | 1000 | 處理每個變更批次之間的延遲以毫秒為單位。 (1000 毫秒為 1 秒) |
MaxChangesPerWorker | 1000 | 每個應用程式背景工作角色所允許的用戶數據表中暫止變更數目上限。 如果變更計數超過此限制,可能會導致向外延展。此設定僅適用於已啟用運行時間驅動調整的 Azure Function Apps。 |
範例host.json檔案
以下是具有選擇性設定host.json檔案的範例:
{
"version": "2.0",
"extensions": {
"Sql": {
"MaxBatchSize": 300,
"PollingIntervalMs": 1000,
"MaxChangesPerWorker": 100
}
},
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"default": "Trace"
}
}
}
local.setting.json
local.settings.json 檔案會儲存本機開發工具所使用的應用程式設定和設定。 只有當您在本機執行專案時,才會使用 local.settings.json 檔案中的設定。 當您將專案發佈至 Azure 時,請務必同時將任何必要的設定新增至函數應用程式的應用程式設定。
重要
因為 local.settings.json 可能包含秘密,例如連接字串,請勿儲存在遠端存放庫。 支援 Functions 的工具,可用來同步處理 local.settings.json 檔案中的設定與專案部署所在之函式應用程式中的應用程式設定。
設定 | 預設 | 描述 |
---|---|---|
Sql_Trigger_BatchSize | 100 | 傳送至觸發程式函式之前,每個觸發程式循環反覆專案所處理的變更數目上限。 |
Sql_Trigger_PollingIntervalMs | 1000 | 處理每個變更批次之間的延遲以毫秒為單位。 (1000 毫秒為 1 秒) |
Sql_Trigger_MaxChangesPerWorker | 1000 | 每個應用程式背景工作角色所允許的用戶數據表中暫止變更數目上限。 如果變更計數超過此限制,可能會導致向外延展。此設定僅適用於已啟用運行時間驅動調整的 Azure Function Apps。 |
範例local.settings.json檔案
以下是具有選擇性設定local.settings.json檔案的範例:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"SqlConnectionString": "",
"Sql_Trigger_MaxBatchSize": 300,
"Sql_Trigger_PollingIntervalMs": 1000,
"Sql_Trigger_MaxChangesPerWorker": 100
}
}
設定變更追蹤 (必要)
設定要與 Azure SQL 觸發程式搭配使用的變更追蹤需要兩個步驟。 您可以從任何支援執行查詢的 SQL 工具完成這些步驟,包括 Visual Studio Code、Azure Data Studio 或 SQL Server Management Studio。
在 SQL 資料庫上啟用變更追蹤,並以要監視之資料表所在的資料庫名稱取代
your database name
:ALTER DATABASE [your database name] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
選項
CHANGE_RETENTION
會指定保留變更追蹤資訊 (變更歷程記錄) 的時間週期。 SQL 資料庫變更歷程記錄的保留可能會影響觸發程式功能。 例如,如果 Azure 函式關閉數天,然後繼續,資料庫將會包含上述設定範例中過去兩天內發生的變更。AUTO_CLEANUP
選項可用來啟用或停用移除舊變更追蹤資訊的清除工作。 如果暫時性問題導致觸發程式無法執行,則關閉自動清除有助於暫停移除比保留期間更舊的資訊,直到問題解決為止。如需變更追蹤選項的詳細資訊,請參閱 SQL 檔。
在資料表上啟用變更追蹤,並以要監視的數據表名稱取代
your table name
(適當時變更架構):ALTER TABLE [dbo].[your table name] ENABLE CHANGE_TRACKING;
觸發程式必須具有受監視之數據表的讀取許可權,以取得變更和變更追蹤系統數據表的讀取許可權。 每個函式觸發程式在架構
az_func
中都有相關聯的變更追蹤數據表和租用數據表。 如果這些數據表還不存在,觸發程式就會建立這些數據表。 如需這些數據結構的詳細資訊,請參閱 Azure SQL 系結連結庫 檔。
啟用運行時間驅動調整
或者,您的函式可以根據擱置中的變更數目自動調整,以在用戶數據表中處理。 若要在使用 SQL 觸發程式時,讓函式在進階方案上正確調整,您必須啟用運行時間調整監視。
在 Azure 入口網站 的函式應用程式中,選擇 [組態],然後在 [函式運行時間設定] 索引標籤上,將 [運行時間規模監視] 轉換成 [開啟]。
重試支援
GitHub 存放庫中提供 SQL 觸發程式 重試支援 和 租用數據表 的詳細資訊。
啟動重試
如果在啟動期間發生例外狀況,則主機運行時間會自動嘗試使用指數輪詢策略重新啟動觸發程式接聽程式。 這些重試會繼續執行,直到接聽程式成功啟動或取消啟動為止。
中斷的連接重試
如果函式成功啟動,但錯誤會導致連線中斷(例如伺服器離線),則函式會繼續嘗試重新開啟連線,直到函式停止或連線成功為止。 如果成功重新建立連線,則會在中斷時挑選處理變更。
請注意,這些重試是在 SqlClient 可以使用 ConnectRetryCount
和 ConnectRetryInterval
連接字串 選項設定的內建閑置連線重試邏輯之外。 先嘗試內建閑置連線重試,如果無法重新連線,則觸發程式系結會嘗試重新建立連線本身。
函式例外狀況重試
如果在處理變更時,使用者函式中發生例外狀況,則會在 60 秒內重試目前正在處理的數據列批次。 在此期間,其他變更會正常處理,但造成例外狀況的批次中的數據列會忽略,直到逾時期間過後。
如果指定數據列的數據列中函數執行失敗五次,則所有未來變更都會完全忽略該數據列。 由於批次中的數據列不具決定性,失敗批次中的數據列可能會在後續調用中以不同的批次結束。 這表示失敗批次中的所有數據列不一定會被忽略。 如果批次中的其他數據列是造成例外狀況的數據列,則「良好」數據列最終可能會出現在未來調用中不會失敗的不同批次中。