クエリ通知の操作
クエリ通知は、SQL Server 2005 および SQL Server Native Client で導入されました。クエリ通知は SQL Server 2005 に導入された Service Broker インフラストラクチャに基づいて構築されており、データが変更されたときにクエリ通知を使用してアプリケーションに通知できます。Web アプリケーションのように、データベースからの情報のキャッシュを用意し、データベースのデータが変更されたときに通知する必要があるアプリケーションでは、この機能が特に有用です。
クエリ通知を使用すると、クエリの基になるデータが変更された場合に、指定されたタイムアウト期間内に通知を要求することができます。通知を要求する際は、サービス名、メッセージ テキスト、サーバーのタイムアウト値などの通知オプションを指定します。通知は Service Broker キューを使用して配信されます。アプリケーションではこのキューにポーリングして、使用可能な通知を確認できます。
クエリ通知オプションの構文を次に示します。
service=<service-name>[;(local database=<database> | broker instance=<broker instance>)]
次に例を示します。
service=mySSBService;local database=mydb
アプリケーションで通知サブスクリプションが作成された直後にそのアプリケーションが終了した場合、通知サブスクリプションを開始するプロセスが終了しても、通知サブスクリプションは有効です。通知サブスクリプションが有効なままなので、通知サブスクリプションの作成時に指定したタイムアウト期間内にデータが変更されると、通知が行われます。通知は、実行されるクエリ、通知オプション、およびメッセージ テキストによって識別されます。また、通知のタイムアウト値を 0 に設定して通知をキャンセルできます。
通知は、一度だけ送信されます。データ変更の通知を連続して行う場合は、各通知が処理された後にクエリを再実行して、新しいサブスクリプションを作成する必要があります。
SQL Server Native Client アプリケーションでは、通常、Transact-SQLRECEIVE コマンドを使用して通知を受け取り、通知オプションで指定したサービスに関連付けられたキューから通知を読み取ります。
注 |
---|
通知を必要とするクエリ内のテーブル名は、dbo.myTable のように、修飾された名前にする必要があります。テーブル名は、2 つの部分を持つ修飾名にする必要があります。3 つまたは 4 つの部分を持つ名前を使用すると、サブスクリプションが無効になります。 |
この通知インフラストラクチャは、SQL Server 2005 で導入されたキュー処理機能に基づいて構築されています。一般的に、サーバーで生成された通知は、後で処理するためにキュー経由で送信されます。SQL Server のクエリ通知に対するサポートの詳細については、「クエリ通知の使用」を参照してください。
クエリ通知を使用するには、クエリとサービスがサーバー上に存在する必要があります。次のような Transact-SQL ステートメントを使用して、クエリやサービスを作成できます。
CREATE QUEUE myQueue
CREATE SERVICE myService ON QUEUE myQueue
([https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
注 |
---|
上記のように、サービスでは定義済みのコントラクト https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification を使用する必要があります。 |
SQL Server Native Client OLE DB プロバイダ
SQL Server Native Client OLE DB プロバイダでは、行セットの変更をコンシューマに通知できます。コンシューマは、行セットの変更のすべてのフェーズで、任意の変更が試行されたときに通知を受け取ります。
注 |
---|
SQL Server Native Client OLE DB プロバイダを使用してクエリ通知をサブスクライブする場合、唯一の有効な方法は、ICommand::Execute を使用してサーバーに通知クエリを渡す方法です。 |
DBPROPSET_SQLSERVERROWSET プロパティ セット
OLE DB によるクエリ通知をサポートするために、次の新しいプロパティが SQL Server Native Client の DBPROPSET_SQLSERVERROWSET プロパティ セットに追加されました。
名前 |
データ型 |
説明 |
---|---|---|
SSPROP_QP_NOTIFICATION_TIMEOUT |
VT_UI4 |
クエリ通知をアクティブのままにしておく秒数。 既定値は 432,000 秒 (5 日) です。最小値は 1 秒であり、最大値は 2^31-1 秒です。 |
SSPROP_QP_NOTIFICATION_MSGTEXT |
VT_BSTR |
通知のメッセージ テキスト。これはユーザーが定義するため、あらかじめ定義済みの書式はありません。 既定値は空の文字列です。1 ~ 2,000 文字を使用してメッセージを指定できます。 |
SSPROP_QP_NOTIFICATION_OPTIONS |
VT_BSTR |
クエリ通知オプション。これらは name=value 構文を使用した文字列で指定されます。ユーザーがサービスを作成して、キューから通知を読み取る必要があります。 既定値は空の文字列です。 |
ステートメントがユーザー トランザクションで実行されたか自動コミットで実行されたか、また、ステートメントが実行されたトランザクションがコミットされたかロールバックされたかに関係なく、通知サブスクリプションは必ずコミットされます。サーバー通知は、次の無効通知条件のいずれかが最初に発生したときに起動します。通知条件は、基になるデータまたはスキーマが変更されるか、タイムアウト期間に到達するかです。通知登録は、起動直後に削除されます。したがって、通知を受け取った後も引き続き更新するには、アプリケーションで再度サブスクライブする必要があります。
他の接続またはスレッドは、接続先キューに通知があるかどうかを確認できます。次に例を示します。
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 以外で、かつ空ではない場合、上記で定義された 3 つのプロパティを含んでいるクエリ通知 TDS ヘッダーが、コマンドが実行されるたびにサーバーに送信されます。どちらかが NULL (または空) の場合、クエリ通知 TDS ヘッダーは送信されず、DB_E_ERRORSOCCURED (または、プロパティが両方とも省略可能に設定されている場合は DB_S_ERRORSOCCURED) が発生し、状態値が DBPROPSTATUS_BADVALUE に設定されます。実行または準備の時点で検証が行われます。同様に、クエリ通知プロパティが SQL Server 2005 より前のバージョンの SQL Server への接続に対して設定されている場合は、DB_S_ERRORSOCCURED が発生します。この場合の状態値は DBPROPSTATUS_NOTSUPPORTED です。
サブスクリプションが開始されても、後続のメッセージが正常に配信されるかどうかは保証されません。また、指定されたサーバー名の妥当性に関するチェックは行われません。
注 |
---|
ステートメントの準備フェーズではサブスクリプションが開始されることはありません。サブスクリプションは、ステートメントを実行したときにのみ開始されます。また、OLE DB Core Services を使用してもクエリ通知は影響を受けません。 |
DBPROPSET_SQLSERVERROWSET プロパティ セットの詳細については、「行セットのプロパティと動作」を参照してください。
SQL Server Native Client ODBC ドライバ
SQL Server Native Client ODBC ドライバでは、SQLGetStmtAttr 関数と SQLSetStmtAttr 関数に次の新しい 3 つの属性が追加されたことにより、クエリ通知がサポートされるようになりました。
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 以外の場合、上記で定義された 3 つの属性を含むクエリ通知 TDS ヘッダーが、コマンドを実行するたびにサーバーに送信されます。どちらかが NULL の場合、クエリ通知 TDS ヘッダーは送信されず、SQL_SUCCESS_WITH_INFO が返されます。SQLPrepare、SqlExecDirect、および SqlExecute に対して検証が行われますが、これらの通知属性が無効の場合はいずれも失敗します。同様に、これらのクエリ通知属性が SQL Server 2005 より前のバージョンの SQL Server に対して設定されている場合、SQL_SUCCESS_WITH_INFO によって実行が失敗します。
注 |
---|
ステートメントの準備段階では、サブスクリプションが開始されることはありません。サブスクリプションを開始できるのは、ステートメントを実行したときのみです。 |
特別なケースおよび制限
通知では、次のデータ型がサポートされていません。
text
ntext
image
これらのいずれかのデータ型を返すクエリに対して通知要求を作成すると、通知サブスクリプションが不可能であるという通知が、すぐに発行されます。
バッチまたはストアド プロシージャに対するサブスクリプション要求を作成すると、そのバッチまたはストアド プロシージャ内で実行される各ステートメントに対して、別個のサブスクリプション要求が作成されます。EXECUTE ステートメントは通知を登録せず、実行されるコマンドへ通知要求を送信します。バッチの場合、実行されるステートメントに対してコンテキストが適用され、さらに同様のルールが適用されます。
既存のアクティブなサブスクリプションと同じテンプレート、パラメータ値、通知 ID、および配信場所を持つ通知のクエリを、同じユーザーが同じデータベース コンテキストで送信すると、既存のサブスクリプションが更新され、新しく指定されたタイムアウトが再設定されます。つまり、同一内容の複数のクエリに対して通知を要求した場合、通知は 1 つだけ送信されます。バッチ内で重複するクエリや、ストアド プロシージャ内で複数回呼び出されたクエリにも、これが当てはまります。