在作業步驟中使用 Token
適用於:SQL Server Azure SQL 受控執行個體
重要
Azure SQL 受控執行個體目前支援多數 (但非全部) 的 SQL Server Agent 功能。 如需詳細資料,請參閱 Azure SQL 受控執行個體與 SQL Server 之間的 T-SQL 差異。
SQL Server Agent 可讓您在 Transact-SQL 作業步驟指令碼中使用 Token。 撰寫作業步驟時使用 Token,所賦予您的彈性與撰寫軟體程式時使用的變數一樣。 在作業步驟指令碼中插入 Token 後,SQL Server Agent 就會先在執行階段取代此 Token,然後再由 Transact-SQL 子系統執行作業步驟。
了解如何使用權杖
重要
只要是具有 Windows 事件記錄檔寫入權限的 Windows 使用者,都可以存取由 SQL Server Agent 警示或 WMI 警示啟動的作業步驟。 為了避免此安全性風險,依預設會停用可在警示啟動作業中使用的 SQL Server Agent Token。 這些 Token 包括: A-DBN、 A-SVR、 A-ERR、 A-SEV、 A-MSG及 WMI(<屬性>) 。 請注意在此版本中,權杖的使用擴充到所有警示。
如果需要使用這些 Token,請先確認只有受信任的 Windows 安全性群組成員 (例如 Administrators 群組) 具有 SQL Server 所在電腦的事件記錄檔寫入權限。 然後以滑鼠右鍵按一下物件總管中的 [SQL Server Agent]、選取 [屬性],然後在 [警示系統] 頁面上選取 [取代回應警示之所有作業的 Token],以啟用這些 Token。
SQL Server Agent Token 取代功能既簡單又有效率:SQL Server Agent 會使用精確的常值字串值來取代 Token。 所有 Token 需區分大小寫。 您的作業步驟必須將這點納入考量,並且必須正確引用您所用的 Token 或將取代字串轉換成正確的資料類型。
例如,您可能會使用下列陳述式,在作業步驟中列印資料庫的名稱:
PRINT N'Current database name is $(ESCAPE_SQUOTE(A-DBN))' ;
在此範例中, ESCAPE_SQUOTE 巨集是使用 A-DBN Token 插入的。 在執行階段, A-DBN Token 將會被取代成正確的資料庫名稱。 逸出巨集會逸出不慎傳入 Token 取代字串的任何單引號。 SQL Server Agent 在最終字串中使用兩個單引號來取代一個單引號。
例如,如果為取代 Token 所傳遞的字串是 AdventureWorks2022'SELECT @@VERSION --
,則由 SQL Server Agent 作業步驟所執行的命令將會是:
PRINT N'Current database name is AdventureWorks2022''SELECT @@VERSION --' ;
在此情況下,插入的陳述式 SELECT @@VERSION
不會執行。 額外的單引號反而會導致伺服器將插入的陳述式剖析成字串。 如果權杖取代字串不包含單引號,就不會逸出任何字元,而且包含權杖的作業步驟會如預期方式執行。
若要在作業步驟中偵錯 Token 的使用方式,請使用 PRINT 陳述式 (例如 PRINT N'$(ESCAPE_SQUOTE(SQLDIR))'
),並將作業步驟輸出儲存至檔案或資料表。 您可以使用 [作業步驟屬性] 對話方塊的 [進階] 頁面來指定作業步驟輸出檔或資料表。
SQL Server Agent Token 和巨集
下表列出並說明 SQL Server Agent 支援的 Token 和巨集。
SQL Server Agent Token
Token | 描述 |
---|---|
(A-DBN) | 資料庫名稱。 若作業是由警示執行,則資料庫名稱值會自動取代作業步驟中的此 Token。 |
(A-SVR) | 伺服器名稱。 若作業是由警示執行,則伺服器名稱值會自動取代作業步驟中的此 Token。 |
(A-ERR) | 錯誤號碼。 若作業是由警示執行,則錯誤號碼值會自動取代作業步驟中的此 Token。 |
(A-SEV) | 錯誤的重要性。 若作業是由警示執行,則錯誤嚴重性值會自動取代作業步驟中的此 Token。 |
(A-MSG) | 訊息文字。 若作業是由警示執行,則訊息文字值會自動取代作業步驟中的此 Token。 |
(JOBNAME) | 作業的名稱。 此權杖僅適用於 SQL Server 2016 和更新版本。 |
(STEPNAME) | 步驟的名稱。 此權杖僅適用於 SQL Server 2016 和更新版本。 |
(DATE) | 目前日期 (格式為 YYYYMMDD)。 |
(INST) | 執行個體名稱。 如果是預設執行個體,此權杖將具有預設執行個體名稱:MSSQLSERVER。 |
(JOBID) | 作業識別碼。 |
(MACH) | 電腦名稱。 |
(MSSA) | 主要 SQLServerAgent 服務名稱。 |
(OSCMD) | 用於執行 CmdExec 作業步驟之程式的前置詞。 |
(SQLDIR) | SQL Server 安裝所在的目錄。 根據預設,此一值為 C:\Program Files\Microsoft SQL Server\MSSQL。 |
(SQLLOGDIR) | SQL Server 錯誤記錄檔資料夾路徑的取代 Token,例如 $(ESCAPE_SQUOTE(SQLLOGDIR))。 此 Token 僅適用於 SQL Server 2014 和更新版本。 |
(STEPCT) | 此步驟已執行之次數的計數 (不包含重試)。 可利用步驟命令來強制結束多重步驟迴圈 (Loop)。 |
(STEPID) | 步驟識別碼。 |
(SRVR) | 執行 SQL Server 的電腦名稱。 如果 SQL Server 執行個體是具名執行個體,則此項目也包括執行個體名稱。 |
(TIME) | 目前時間 (格式為 HHMMSS)。 |
(STRTTM) | 開始執行作業的時間 (格式為 HHMMSS)。 |
(STRTDT) | 開始執行作業的日期 (格式為 YYYYMMDD)。 |
(WMI( <屬性> )) | 對於回應 WMI 警示所執行的作業,這是 <屬性> 指定的屬性值。 例如,$(WMI(DatabaseName)) 提供造成警示執行之 WMI 事件的 DatabaseName 屬性值。 |
SQL Server Agent 逸出巨集
逸出巨集 | 描述 |
---|---|
$(ESCAPE_SQUOTE(<Token 名稱>)) | 在 Token 取代字串中逸出單引號 (')。 使用兩個單引號來取代一個單引號。 |
$(ESCAPE_DQUOTE(<Token 名稱>)) | 在 Token 取代字串中逸出雙引號 (")。 使用兩個雙引號來取代一個雙引號。 |
$(ESCAPE_RBRACKET(<Token 名稱>)) | 在 Token 取代字串中逸出右方括號 (])。 使用兩個右方括號來取代一個右方括號。 |
$(ESCAPE_NONE(<Token 名稱>)) | 取代 Token,但不逸出字串中的任何字元。 提供這個巨集的目的,是為了在 Token 取代字串只能由受信任使用者提供的環境下,支援回溯相容性。 如需詳細資訊,請參閱本主題後面的「將作業步驟更新成使用巨集」。 |
更新使用巨集的作業步驟
下表說明 SQL Server Agent 處理 Token 取代的方法。 若要開啟或關閉取代 Token,請以滑鼠右鍵按一下物件總管中的 [SQL Server Agent],並選取 [屬性],然後在 [警示系統] 頁面上選取或清除 [取代回應警示之所有作業的 Token] 核取方塊。
Token 語法 | 警示 Token 取代開啟 | 警示 Token 取代關閉 |
---|---|---|
使用 ESCAPE 巨集 | 作業中的所有 Token 都會順利被取代。 | 由警示啟動的權杖不會被取代。 這些 Token 包括: A-DBN、 A-SVR、 A-ERR、 A-SEV、 A-MSG及 WMI(<屬性>) 。 其他靜態 Token 則會順利被取代。 |
不使用 ESCAPE 巨集 | 所有包含 Token 的作業都會失敗。 | 所有包含 Token 的作業都會失敗。 |
Token 語法更新範例
以下是令牌權杖範例,可協助說明如何使用這些命令。
A. 在非巢狀字串中使用權杖
下列範例將說明如何使用正確的逸出巨集來更新簡單的非巢狀指令碼。 執行更新指令碼之前,下列作業步驟指令碼會使用一個作業步驟 Token 來列印正確的資料庫名稱:
PRINT N'Current database name is $(A-DBN)' ;
執行更新指令碼之後,會在 ESCAPE_NONE
Token 前面插入 A-DBN
巨集。 由於單引號是用來分隔 PRINT 字串,所以您必須依照下列方式插入 ESCAPE_SQUOTE
巨集,藉以更新此作業步驟:
PRINT N'Current database name is $(ESCAPE_SQUOTE(A-DBN))' ;
B. 在巢狀字串中使用權杖
在 Token 用於巢狀字串或陳述式的作業步驟指令碼中,巢狀陳述式應該先重新撰寫成多個陳述式,然後再插入正確的逸出巨集。
例如,請考慮下列使用 A-MSG
權杖而且尚未使用逸出巨集更新的作業步驟:
PRINT N'Print ''$(A-MSG)''' ;
執行更新指令碼之後,會使用此 Token 插入 ESCAPE_NONE
巨集。 不過,在此情況下,您必須依照下列方式重新撰寫不使用巢狀的指令碼,並插入 ESCAPE_SQUOTE
巨集,以便適當逸出可能會傳入 Token 取代字串的分隔符號:
DECLARE @msgString nvarchar(max);
SET @msgString = '$(ESCAPE_SQUOTE(A-MSG))';
SET @msgString = QUOTENAME(@msgString,'''');
PRINT N'Print ' + @msgString;
注意
請注意此範例中,QUOTENAME 函數會設定引號字元。
C. 使用權杖搭配 ESCAPE_NONE 巨集
下列範例是指令碼的一部分,而這個指令碼會從 資料表擷取 job_id 並使用 JOBID 權杖來擴展 @JobID 變數 (之前在指令碼中宣告成二進位資料類型)。
注意
請注意,由於二進位資料類型不需要任何分隔符號,所以 巨集會搭配 Token 使用。 您不需要在執行更新指令碼之後,更新此作業步驟。
DECLARE @JobID uniqueidentifier
SET @JobID = $(ESCAPE_NONE(JOBID))
這會將 JOBID 權杖中的值直接指派給 @JobID,排除不必要的資料庫查詢和隱含轉換,以解決 C 節中引發的問題。