使用查詢通知

適用於:SQL ServerAzure SQL 受控執行個體

重要

SQL Server Native Client (通常縮寫為 SNAC) 已從 SQL Server 2022 (16.x) 和 SQL Server Management Studio 19 (SSMS) 中移除。 不建議使用 SQL Server Native Client (SQLNCLI 或 SQLNCLI11) 和舊版 Microsoft OLE DB Provider for SQL Server (SQLOLEDB) 開發新的應用程式。 往後請改用新的 Microsoft OLE DB Driver (MSOLEDBSQL) for SQL Server 或最新的 Microsoft ODBC Driver for SQL Server。 如需 SQL Server 資料庫引擎元件隨附的 SQLNCLI(版本 2012 到 2019),請參閱此 支援生命週期例外狀況

SQL Server 2005 (9.x) 和 SQL Server Native Client 中引進了查詢通知。 以 SQL Server 2005 (9.x) 中引進的 Service Broker 基礎結構為基礎,查詢通知可讓應用程式在資料變更時收到通知。 此功能對於從資料庫中提供資訊快取的應用程式 (如 Web 應用程式),及需要在來源資料變更時收到通知的應用程式來說非常有用。

查詢通知可讓您在查詢的基礎資料變更時,在指定的逾時期間內要求通知。 通知要求會指定通知選項,其中包括伺服器的服務名稱、郵件內文和逾時值。 通知會透過 Service Broker 佇列傳遞,應用程式可能會輪詢是否有可用的通知。

查詢通知選項字串的語法為:

service=<service-name>[;(local database=<database> | broker instance=<broker instance>)]

例如:

service=mySSBService;local database=mydb

通知訂閱會超過起始它們的程式,因為應用程式可能會建立通知訂閱,然後終止。 訂閱會維持有效狀態,如果建立訂閱時指定的逾時期間內的資料變更,就會發生通知。 查詢執行、通知選項和郵件內文會識別通知,而且可以藉由將其逾時值設定為零來取消。

通知只會傳送一次。 若要持續通知資料變更,必須在處理每個通知之後,重新執行查詢來建立新的訂用帳戶。

SQL Server Native Client 應用程式通常會使用 Transact-SQL RECEIVE 命令,從通知選項中指定的服務讀取佇列中的通知。

注意

資料表名稱必須在需要通知的查詢中限定,例如 dbo.myTable 。 資料表名稱必須以兩個部分名稱限定。 如果使用三或四部份的名稱,則訂閱無效。

通知基礎結構是依照 SQL Server 2005 (9.x) 中引進的佇列功能而建立。 一般而言,伺服器產生的通知會透過這些佇列傳送,以供稍後處理。

若要使用查詢通知,佇列和服務必須存在於伺服器上。 您可以使用類似下列的 Transact-SQL 來建立這些專案:

CREATE QUEUE myQueue  
CREATE SERVICE myService ON QUEUE myQueue   
  
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])  

注意

服務必須使用預先定義的合約 http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification ,如上所示。

SQL Server Native Client OLE DB 提供者

SQL Server Native Client OLE DB 提供者支援資料列集修改的取用者通知。 取用者會在資料列集修改的每個階段以及任何嘗試的變更時收到通知。

注意

使用 ICommand::Execute 將通知查詢傳遞至伺服器,是使用 SQL Server Native Client OLE DB 提供者訂閱查詢通知的唯一有效方式。

DBPROPSET_SQLSERVERROWSET屬性集

為了支援透過 OLE DB 的查詢通知,SQL Server Native Client 會將下列新屬性新增至DBPROPSET_SQLSERVERROWSET屬性集。

名稱 類型​ 描述
SSPROP_QP_NOTIFICATION_TIMEOUT VT_UI4 查詢通知要維持使用中的秒數。

預設值為 432000 秒(5 天)。 最小值為 1 秒,最大值為 2^31-1 秒。
SSPROP_QP_NOTIFICATION_MSGTEXT VT_BSTR 通知的訊息文字。 這是使用者定義的,而且沒有預先定義的格式。

根據預設,字串是空的。 您可以使用 1-2000 個字元來指定訊息。
SSPROP_QP_NOTIFICATION_OPTIONS VT_BSTR 查詢通知選項。 這些是在具有 名稱 = 值 語法的字串中指定。 使用者負責建立此服務以及從佇列讀取通知。

預設值是空字串。

無論語句是在使用者交易或自動認可中執行,還是語句執行認可或回復的交易,通知訂閱一律會認可。 伺服器通知會在發生下列任何無效通知條件時觸發:基礎資料或結構描述變更,或達到逾時期限 (視何者為先)。 一旦引發通知註冊,就會刪除通知註冊。 因此,在收到通知時,應用程式必須再次訂閱,以防他們想要取得進一步的更新。

其他的連接或執行緒可以檢查目的地佇列是否有通知。 例如:

WAITFOR (RECEIVE * FROM MyQueue);   // Where MyQueue is the queue name.   

請注意,SELECT * 不會從佇列中刪除專案,不過 RECEIVE * FROM。 如果佇列是空的,這麼做會使伺服器延滯。 如果在呼叫時有佇列專案,則會立即傳回它們:否則,呼叫會等到佇列專案完成為止。

RECEIVE * FROM MyQueue  

如果佇列是空的,這個語句會立即傳回空的結果集;否則會傳回所有佇列通知。

如果SSPROP_QP_NOTIFICATION_MSGTEXT和SSPROP_QP_NOTIFICATION_OPTIONS非 Null 和非空白,則包含上述三個屬性的查詢通知 TDS 標頭會傳送至伺服器,並執行命令。 如果其中任一項為 null(或空白),則不會傳送標頭並引發DB_E_ERRORSOCCURRED,或 DB_S_ERRORSOCCURRED如果屬性都標示為選擇性,則會將狀態值設定為DBPROPSTATUS_BADVALUE。 驗證會在執行/準備時發生。 同樣地,當查詢通知屬性設定為 SQL Server 2005 (9.x) 之前的 SQL Server 版本連線時,就會引發DB_S_ERRORSOCCURED。 在此案例中,狀態值是DBPROPSTATUS_NOTSUPPORTED。

起始訂用帳戶並不保證後續訊息會順利傳遞。 此外,不會檢查指定之服務名稱的有效性。

注意

準備語句永遠不會造成訂用帳戶起始;只有語句執行才會達到此目的,且查詢通知不會受到使用 OLE DB 核心服務的影響。

如需屬性集DBPROPSET_SQLSERVERROWSET的詳細資訊,請參閱 資料列集屬性和行為

SQL Server Native Client ODBC Driver

SQL Server Native Client ODBC 驅動程式透過將三個新屬性新增至 SQLGetStmtAttr SQLSetStmtAttr 函式,支援查詢通知:

  • SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT

  • SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS

  • SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT

如果SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT和SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS不是 Null,則每次執行命令時,都會將包含上述三個屬性的查詢通知 TDS 標頭傳送到伺服器。 如果其中一個為 null,則不會傳送標頭,並傳回SQL_SUCCESS_WITH_INFO。 驗證會在 SQLPrepare 函式 SqlExecDirect SqlExecute 發生,如果屬性無效,所有驗證都會失敗。 同樣地,當 SQL Server 2005 (9.x) 之前,針對 SQL Server 版本設定這些查詢通知屬性時,執行會失敗並SQL_SUCCESS_WITH_INFO。

注意

準備語句永遠不會造成訂用帳戶起始;訂閱可以透過語句執行來起始。

特殊案例和限制

通知不支援下列資料類型:

  • text

  • ntext

  • image

如果針對傳回這些類型之查詢發出通知要求,通知會立即引發,並指定無法指定通知訂閱。

如果針對批次或預存程式提出訂閱要求,則會針對批次或預存程式內執行的每個語句提出個別的訂用帳戶要求。 EXECUTE 語句不會註冊通知,但會將通知要求傳送至執行的命令。 如果是批次,內容將會套用至已執行的語句,而且適用上述相同的規則。

提交相同資料庫內容下相同使用者所提交的通知查詢,並具有相同範本、相同的參數值、相同的通知識別碼,以及現有使用中訂用帳戶的相同傳遞位置,將會更新現有的訂用帳戶,重設新的指定逾時。這表示如果針對相同的查詢要求通知,則只會傳送一個通知。 這會套用至批次中重複的查詢,或呼叫多次的預存程式中的查詢。

另請參閱

SQL Server Native Client 功能