Utilizzo delle notifiche delle query
Si applica a: SQL Server Istanza gestita di SQL di Azure
Importante
SQL Server Native Client (SNAC) non viene fornito con:
- SQL Server 2022 (16.x) e versioni successive
- SQL Server Management Studio 19 e versioni successive
SQL Server Native Client (SQLNCLI o SQLNCLI11) e il provider OLE DB Microsoft legacy per SQL Server (SQLOLEDB) non sono consigliati per lo sviluppo di nuove applicazioni.
Per i nuovi progetti, usare uno dei driver seguenti:
Per SQLNCLI fornito come componente del motore di database di SQL Server (versioni dal 2012 al 2019), vedere questa Eccezione relativa al ciclo di vita del supporto.
Le notifiche delle query sono state introdotte in SQL Server 2005 (9.x) e SQL Server Native Client. Basato sull'infrastruttura di Service Broker introdotta in SQL Server 2005 (9.x), le notifiche di query consentono alle applicazioni di ricevere notifiche quando i dati sono stati modificati. Questa caratteristica è particolarmente utile per le applicazioni che forniscono una cache di informazioni provenienti da un database, ad esempio un'applicazione Web, e devono essere notificate quando i dati di origine vengono modificati.
Le notifiche delle query consentono di richiedere una notifica entro un determinato periodo di timeout quando i dati sottostanti di una query cambiano. La richiesta di notifica specifica le opzioni di notifica che includono il nome del servizio, il testo del messaggio e il valore di timeout per il server. Le notifiche vengono recapitate tramite una coda di Service Broker di cui le applicazioni possono eseguire il polling delle notifiche disponibili.
La sintassi delle opzioni delle notifiche delle query è la seguente:
service=<service-name>[;(local database=<database> | broker instance=<broker instance>)]
Ad esempio:
service=mySSBService;local database=mydb
Le sottoscrizioni di notifica sopravvivono al processo che le avvia, in quanto un'applicazione può creare una sottoscrizione di notifica e quindi terminare. La sottoscrizione rimane valida e la notifica verrà creata se i dati vengono modificati nel periodo di timeout specificato al momento della creazione della sottoscrizione. Una notifica viene identificata dalla query eseguita, dalle opzioni di notifica e dal testo del messaggio e può essere annullata impostandone il valore di timeout su zero.
Le notifiche vengono inviate una sola volta. Per la notifica continua delle modifiche dei dati, è necessario creare una nuova sottoscrizione rieseguendo la query al termine dell'elaborazione di ogni notifica.
Le applicazioni SQL Server Native Client in genere ricevono notifiche usando il comando TRANSACT-SQL RECEIVE per leggere le notifiche dalla coda associata al servizio specificato nelle opzioni di notifica.
Nota
I nomi di tabella devono essere qualificati nelle query per le quali è necessaria la notifica, ad esempio dbo.myTable
, e devono essere qualificati con nomi in due parti. La sottoscrizione non è valida se vengono utilizzati nomi in tre o quattro parti.
L'infrastruttura della notifica si basa su una caratteristica di accodamento introdotta in SQL Server 2005 (9.x). In genere, le notifiche generate sul server vengono inviate tramite queste code in modo da essere elaborate in un secondo momento.
Per utilizzare le notifiche delle query è necessario che sul server siano disponibili una coda e un servizio. Questi possono essere creati usando Transact-SQL in modo simile al seguente:
CREATE QUEUE myQueue
CREATE SERVICE myService ON QUEUE myQueue
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
Nota
Come mostrato sopra, il servizio deve utilizzare il contratto predefinito http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification
.
Provider OLE DB di SQL Server Native Client
Il provider OLE DB di SQL Server Native Client supporta la notifica consumer per la modifica del set di righe. Il consumer riceve una notifica a ogni fase di modifica dei set di righe e a ogni tentativo di modifica.
Nota
Il passaggio di una query di notifica al server con ICommand::Execute è l'unico modo valido per sottoscrivere le notifiche di query con il provider OLE DB di SQL Server Native Client.
Set di proprietà DBPROPSET_SQLSERVERROWSET
Per supportare le notifiche di query tramite OLE DB, SQL Server Native Client aggiunge le nuove proprietà seguenti al set di proprietà DBPROPSET_SQLSERVERROWSET.
Nome | Tipo | Descrizione |
---|---|---|
SSPROP_QP_NOTIFICATION_TIMEOUT | VT_UI4 | Numero di secondi durante i quali la notifica di query deve rimanere attiva. Il valore predefinito è 432000 secondi (5 giorni). Il valore minimo è 1 secondo e il valore massimo è 2^31-1 secondi. |
SSPROP_QP_NOTIFICATION_MSGTEXT | VT_BSTR | Testo del messaggio di notifica. Tale testo è definito dall'utente e non presenta un formato predefinito. Per impostazione predefinita, la stringa è vuota. È possibile specificare un messaggio utilizzando da 1 a 2000 caratteri. |
SSPROP_QP_NOTIFICATION_OPTIONS | VT_BSTR | Opzioni di notifica delle query. Tali opzioni vengono specificate in una stringa con la sintassi nome=valore. L'utente è responsabile della creazione del servizio e della lettura delle notifiche all'esterno della coda. Il valore predefinito è una stringa vuota. |
Il commit della sottoscrizione di notifica viene sempre eseguito, indipendentemente dall'esecuzione dell'istruzione in una transazione utente o in modalità di commit automatico o a prescindere se la transazione in cui è stata eseguita l'istruzione sia stata sottoposta a commit o a rollback. La notifica server viene generata in seguito a una delle condizioni di notifica non valide seguenti: modifica dello schema o dei dati sottostanti o raggiungimento del periodo di timeout, a seconda dell'evento che si verifica per primo. Le registrazioni della notifica vengono eliminate subito dopo essere state generate. In seguito alla ricezione delle notifiche, è pertanto necessario che venga effettuata nuovamente la sottoscrizione se si desidera ottenere ulteriori aggiornamenti.
Un'altra connessione o un altro thread può verificare la presenza di notifiche nella coda di destinazione. Ad esempio:
WAITFOR (RECEIVE * FROM MyQueue); // Where MyQueue is the queue name.
Si noti che SELECT * non elimina la voce dalla coda, ma RECEIVE * FROM does. Di conseguenza un thread del server viene bloccato se la coda è vuota. Se al momento della chiamata sono presenti voci nella coda, vengono restituite immediatamente. In caso contrario, la chiamata resta in attesa finché non viene creata una voce della coda.
RECEIVE * FROM MyQueue
Questa istruzione restituisce immediatamente un set di risultati vuoto se la coda è vuota. In caso contrario, restituisce tutte le notifiche della coda.
Se le proprietà SSPROP_QP_NOTIFICATION_MSGTEXT e SSPROP_QP_NOTIFICATION_OPTIONS sono diverse da Null e non vuote, l'intestazione TDS delle notifiche delle query contenente le tre proprietà definite sopra viene inviata al server a ogni esecuzione del comando. Se una di esse è Null o vuota, l'intestazione non viene inviata e viene generato DB_E_ERRORSOCCURRED, o DB_S_ERRORSOCCURRED se le proprietà sono entrambe contrassegnate come facoltative, e il valore dello stato viene impostato su DBPROPSTATUS_BADVALUE. La convalida viene effettuata in fase di esecuzione/preparazione. Analogamente, DB_S_ERRORSOCCURED viene generato quando le proprietà di notifica delle query vengono impostate per le connessioni alle versioni di SQL Server precedenti a SQL Server 2005 (9.x). Il valore dello stato in questo caso è DBPROPSTATUS_NOTSUPPORTED.
L'avvio di una sottoscrizione non garantisce il corretto recapito dei messaggi successivi. Inoltre, non viene effettuato alcun controllo della validità del nome di servizio specificato.
Nota
La preparazione delle istruzioni non causerà mai l'avvio della sottoscrizione. Tale operazione verrà effettuata solo mediante l'esecuzione delle istruzioni. L'uso dei servizi OLE DB di base non influisce sulle notifiche delle query.
Per altre informazioni sul set di proprietà DBPROPSET_SQLSERVERROWSET, vedere Proprietà e comportamenti del set di righe.
Driver ODBC di SQL Server Native Client
Il driver ODBC di SQL Server Native Client supporta le notifiche di query tramite l'aggiunta di tre nuovi attributi alle funzioni SQLGetStmtAttr e SQLSetStmtAttr :
SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT
SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS
SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT
Se le proprietà SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT e SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS sono diverse da Null, l'intestazione TDS delle notifiche delle query contenente i tre attributi definiti sopra verrà inviata al server ogni volta che il comando viene eseguito. Se una di esse è Null, l'intestazione non viene inviata e viene restituito SQL_SUCCESS_WITH_INFO. La convalida viene eseguita sulla funzione SQLPrepare, SqlExecDirect e SqlExecute, che hanno esito negativo se gli attributi non sono validi. Analogamente, quando questi attributi di notifica delle query vengono impostati per le versioni di SQL Server precedenti a SQL Server 2005 (9.x), l'esecuzione ha esito negativo con SQL_SUCCESS_WITH_INFO.
Nota
La preparazione delle istruzioni non causerà mai l'avvio della sottoscrizione. Tale operazione verrà effettuata solo mediante l'esecuzione delle istruzioni.
Casi e restrizioni speciali
I tipi di dati seguenti non sono supportati per le notifiche:
Testo
ntext
Immagine
Se viene effettuata una richiesta di notifica per una query che restituisce uno di questi tipi, la notifica viene generata immediatamente, indicando che la sottoscrizione di notifica non è riuscita.
Se una richiesta di sottoscrizione viene eseguita per un batch o una stored procedure, verrà eseguita una richiesta di sottoscrizione separata per ogni istruzione eseguita all'interno del batch o della stored procedure. Le istruzioni EXECUTE non registreranno una notifica, ma invieranno la richiesta di notifica al comando eseguito. Nel caso di un batch, il contesto verrà applicato alle istruzioni eseguite e verranno applicate le stesse regole illustrate in precedenza.
L'invio di una query per la notifica inviata dallo stesso utente nello stesso contesto del database e ha lo stesso modello, gli stessi valori di parametro, lo stesso ID notifica e la stessa posizione di recapito di una sottoscrizione attiva esistente, rinnova la sottoscrizione esistente, reimpostando il nuovo timeout specificato. Ciò significa che se viene richiesta una notifica per query identiche, verrà inviata una sola notifica. Questa restrizione è applicabile a una query duplicata in un batch o a una query in una stored procedure chiamata più volte.