Trabalhando com notificações de consulta
Aplica-se a:SQL ServerAzure SQL Managed Instance
Importante
SQL Server Native Client (SNAC) não é fornecido com:
- SQL Server 2022 (16.x) e versões posteriores
- SQL Server Management Studio 19 e versões posteriores
O SQL Server Native Client (SQLNCLI ou SQLNCLI11) e o Microsoft OLE DB Provider for SQL Server (SQLOLEDB) herdado não são recomendados para o desenvolvimento de novos aplicativos.
Para novos projetos, use um dos seguintes drivers:
Para SQLNCLI fornecido como um componente do Mecanismo de Banco de Dados do SQL Server (versões de 2012 a 2019), consulte esta exceção Ciclo de vida do suporte.
As notificações de consulta foram introduzidas no SQL Server 2005 (9.x) e no SQL Server Native Client. Com base na infraestrutura do Service Broker introduzida no SQL Server 2005 (9.x), as notificações de consulta permitem que os aplicativos sejam notificados quando os dados forem alterados. Esse recurso é particularmente útil para aplicativos que fornecem um cache de informações de um banco de dados, como um aplicativo Web, e precisam ser notificados quando os dados de origem são alterados.
As notificações de consulta permitem que você solicite uma notificação dentro de um período de tempo limite especificado quando os dados subjacentes de uma consulta forem alterados. A solicitação de notificação especifica as opções de notificação, que incluem o nome do serviço, o texto da mensagem e o valor de tempo limite para o servidor. As notificações são entregues por meio de uma fila do Service Broker que os aplicativos podem pesquisar notificações disponíveis.
A sintaxe da cadeia de opções de notificações de consulta é:
service=<service-name>[;(local database=<database> | broker instance=<broker instance>)]
Por exemplo:
service=mySSBService;local database=mydb
As assinaturas de notificação sobrevivem ao processo que as inicia, pois um aplicativo pode criar uma assinatura de notificação e, em seguida, encerrar. A assinatura permanece válida e a notificação ocorrerá se os dados forem alterados dentro do período de tempo limite especificado quando a assinatura foi criada. Uma notificação é identificada pela consulta executada, pelas opções de notificação e pelo texto da mensagem e pode ser cancelada definindo seu valor de tempo limite como zero.
As notificações são enviadas apenas uma vez. Para notificação contínua de alteração de dados, uma nova assinatura deve ser criada executando novamente a consulta após cada notificação ser processada.
Os aplicativos do SQL Server Native Client normalmente recebem notificações usando o comando Transact-SQL RECEIVE para ler notificações da fila associada ao serviço especificado nas opções de notificação.
Observação
Os nomes das tabelas devem ser qualificados em consultas para as quais é necessária notificação, por exemplo, dbo.myTable
. Os nomes das tabelas devem ser qualificados com dois nomes de partes. A subscrição é inválida se forem utilizados nomes de três ou quatro partes.
A infraestrutura de notificação é criada com base em um recurso de enfileiramento introduzido no SQL Server 2005 (9.x). Em geral, as notificações geradas no servidor são enviadas através dessas filas para serem processadas posteriormente.
Para usar notificações de consulta, uma fila e um serviço devem existir no servidor. Estes podem ser criados usando Transact-SQL semelhante ao seguinte:
CREATE QUEUE myQueue
CREATE SERVICE myService ON QUEUE myQueue
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
Observação
O serviço deve utilizar a http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification
contratual predefinida, conforme indicado acima.
Provedor OLE DB do SQL Server Native Client
O provedor OLE DB do SQL Server Native Client dá suporte à notificação do consumidor sobre a modificação do conjunto de linhas. O consumidor recebe uma notificação em todas as fases da modificação do conjunto de linhas e em qualquer tentativa de alteração.
Observação
Passar uma consulta de notificações para o servidor com ICommand::Execute é a única maneira válida de assinar notificações de consulta com o provedor OLE DB do SQL Server Native Client.
O conjunto de propriedades DBPROPSET_SQLSERVERROWSET
Para dar suporte a notificações de consulta por meio do OLE DB, O SQL Server Native Client adiciona as novas propriedades a seguir ao conjunto de propriedades DBPROPSET_SQLSERVERROWSET.
Designação | Tipo | Descrição |
---|---|---|
SSPROP_QP_NOTIFICATION_TIMEOUT | VT_UI4 | O número de segundos que a notificação de consulta deve permanecer ativa. O padrão é 432000 segundos (5 dias). O valor mínimo é 1 segundo e o valor máximo é 2^31-1 segundos. |
SSPROP_QP_NOTIFICATION_MSGTEXT | VT_BSTR | O texto da mensagem da notificação. Isso é definido pelo usuário e não tem formato predefinido. Por padrão, a cadeia de caracteres está vazia. Você pode especificar uma mensagem usando de 1 a 2000 caracteres. |
SSPROP_QP_NOTIFICATION_OPTIONS | VT_BSTR | As opções de notificação de consulta. Eles são especificados em uma cadeia de caracteres com nome=valor sintaxe. O usuário é responsável por criar o serviço e ler as notificações fora da fila. O padrão é uma cadeia de caracteres vazia. |
A assinatura de notificação é sempre confirmada, independentemente de a instrução ter sido executada em uma transação de usuário ou em confirmação automática ou se a transação na qual a instrução foi executada foi confirmada ou revertida. A notificação do servidor é acionada em qualquer uma das seguintes condições de notificação inválidas: alteração de dados ou esquema subjacentes, ou quando o período de tempo limite é atingido; consoante o que ocorrer primeiro. Os registros de notificação são excluídos assim que são acionados. Portanto, ao receber notificações, o aplicativo deve se inscrever novamente caso queira obter mais atualizações.
Outra conexão ou thread pode verificar a fila de destino para notificações. Por exemplo:
WAITFOR (RECEIVE * FROM MyQueue); // Where MyQueue is the queue name.
Observe que SELECT * não exclui a entrada da fila, no entanto, RECEIVE * FROM faz. Isso interrompe um thread de servidor se a fila estiver vazia. Se houver entradas na fila no momento da chamada, elas são devolvidas imediatamente; caso contrário, a chamada aguarda até que uma entrada na fila seja feita.
RECEIVE * FROM MyQueue
Esta instrução retorna imediatamente um conjunto de resultados vazio se a fila estiver vazia; caso contrário, ele retorna todas as notificações de fila.
Se SSPROP_QP_NOTIFICATION_MSGTEXT e SSPROP_QP_NOTIFICATION_OPTIONS forem não-NULL e não vazios, o cabeçalho TDS de notificações de consulta contendo as três propriedades definidas acima será enviado ao servidor com cada execução do comando. Se um deles for nulo (ou vazio), o cabeçalho não será enviado e DB_E_ERRORSOCCURRED será gerado (ou DB_S_ERRORSOCCURRED se as propriedades estiverem marcadas como opcionais) e o valor de status será definido como DBPROPSTATUS_BADVALUE. A validação ocorre em Executar/Preparar. Da mesma forma, DB_S_ERRORSOCCURRED é gerado quando as propriedades de notificação de consulta são definidas para conexões com versões do SQL Server anteriores ao SQL Server 2005 (9.x). O valor de status neste caso é DBPROPSTATUS_NOTSUPPORTED.
Iniciar uma assinatura não garante que as mensagens subsequentes serão entregues com sucesso. Além disso, não é feita qualquer verificação quanto à validade do nome do serviço especificado.
Observação
A preparação de declarações nunca fará com que a subscrição seja iniciada; somente a execução da instrução alcançará isso e as notificações de consulta não serão afetadas pelo uso dos serviços principais do OLE DB.
Para obter mais informações sobre o conjunto de propriedades DBPROPSET_SQLSERVERROWSET, consulte Propriedades e comportamentos do conjunto de linhas.
SQL Server Native Client ODBC Driver
O driver ODBC do SQL Server Native Client dá suporte a notificações de consulta por meio da adição de três novos atributos às funções SQLGetStmtAttr e SQLSetStmtAttr:
SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT
SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS
SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT
Se SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT e SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS não forem NULL, o cabeçalho TDS de notificações de consulta contendo os três atributos definidos acima será enviado ao servidor cada vez que o comando for executado. Se qualquer um deles for nulo, o cabeçalho não será enviado e SQL_SUCCESS_WITH_INFO será retornado. A validação ocorre em de Função SQLPrepare, SqlExecDirect e SqlExecute, que falham se os atributos não forem válidos. Da mesma forma, quando esses atributos de notificação de consulta são definidos para versões do SQL Server antes do SQL Server 2005 (9.x), a execução falha com SQL_SUCCESS_WITH_INFO.
Observação
Preparar declarações nunca fará com que a subscrição seja iniciada; A subscrição pode ser iniciada através da execução de instruções.
Casos Especiais e Restrições
Os seguintes tipos de dados não são suportados para notificações:
texto
ntext
imagem
Se for feita uma solicitação de notificação para uma consulta que retorna qualquer um desses tipos, a notificação será acionada imediatamente, especificando que a assinatura de notificação não era possível.
Se uma solicitação de assinatura for feita para um lote ou procedimento armazenado, uma solicitação de assinatura separada será feita para cada instrução executada dentro do lote ou procedimento armazenado. As instruções EXECUTE não registrarão uma notificação, mas enviarão a solicitação de notificação para o comando executado. Se for um lote, o contexto será aplicado às instruções executadas e as mesmas regras descritas acima se aplicam.
O envio de uma consulta para notificação que foi enviada pelo mesmo usuário no mesmo contexto de banco de dados e tem o mesmo modelo, os mesmos valores de parâmetro, a mesma ID de notificação e o mesmo local de entrega de uma assinatura ativa existente renovará a assinatura existente, redefinindo o novo tempo limite especificado. Isto significa que, se for solicitada uma notificação para consultas idênticas, apenas será enviada uma notificação. Isso se aplicaria a uma consulta duplicada em um lote ou a uma consulta em um procedimento armazenado que foi chamado várias vezes.