Procedure consigliate per i filtri di riga basati sul tempoBest Practices for Time-Based Row Filters

Gli utenti delle applicazioni hanno spesso la necessità di recuperare da diverse tabelle determinati subset di dati basati sul tempo.Users of applications often require a time-based subset of data from a table. Un venditore potrebbe ad esempio richiedere i dati relativi agli ordini dell'ultima settimana, così come un responsabile della pianificazione di eventi potrebbe aver bisogno di recuperare i dati relativi agli eventi della settimana in arrivo.For instance, a salesperson might require data for orders in the last week, or an event planner might require data for events in the upcoming week. Per soddisfare queste richieste, le applicazioni utilizzano, in numerosi casi, query contenenti la funzione GETDATE() .In many cases, applications use queries containing the GETDATE() function to accomplish this. Si consideri l'istruzione di filtro di riga seguente:Consider the following row filter statement:

WHERE SalesPersonID = CONVERT(INT,HOST_NAME()) AND OrderDate >= (GETDATE()-6)  

Con un filtro di questo tipo, l'esecuzione dell'agente di merge ha in genere due risultati: le righe che soddisfano il filtro vengono replicate nei Sottoscrittori, mentre le righe che non soddisfano più il filtro vengono rimosse dai Sottoscrittori.With a filter of this type, it is usually assumed that two things always occur when the Merge Agent runs: rows that satisfy this filter are replicated to Subscribers; and rows that no longer satisfy this filter are cleaned up at Subscribers. Per altre informazioni sulle opzioni di filtro con HOST_NAME(), vedere Filtri di riga con parametri. La replica di tipo merge, tuttavia, consente di replicare e pulire esclusivamente i dati che sono stati modificati dopo l'ultima sincronizzazione, indipendentemente dalla modalità di definizione di un filtro di riga per tali dati.(For more information about filtering with HOST_NAME(), see Parameterized Row Filters.) However, merge replication only replicates and cleans up data that has changed since the last synchronization, regardless of how you define a row filter for that data.

Affinché la replica di tipo merge elabori una riga, è necessario che i dati contenuti in tale riga soddisfino il filtro di riga e che siano stati modificati dopo l'ultima sincronizzazione.For merge replication to process a row, the data in the row must satisfy the row filter, and it must have changed since the last synchronization. Nel caso della tabella SalesOrderHeader , OrderDate viene immesso quando si inserisce una riga.In the case of the SalesOrderHeader table, OrderDate is entered when a row is inserted. Le righe vengono quindi replicate nel Sottoscrittore come previsto poiché l'inserimento rappresenta una modifica ai dati.Rows are replicated to the Subscriber as expected because the insert is a data change. Se tuttavia nel Sottoscrittore sono presenti righe che non soddisfano più il filtro, ovvero sono relative a ordini immessi da più di sette giorni, queste verranno rimosse dal Sottoscrittore a meno che non siano state aggiornate per altri motivi.However, if there are rows at the Subscriber that no longer satisfy the filter (they are for orders older than seven days), they are not removed from the Subscriber unless they were updated for some other reason.

L'esempio del responsabile della pianificazione di eventi evidenzia ulteriormente il problema legato a questo tipo di filtro.The case of the event planner further highlights the issue with this type of filtering. Si consideri di utilizzare il filtro seguente per una tabella Events :Consider the following filter for an Events table:

WHERE EventCoordID = CONVERT(INT,HOST_NAME()) AND EventDate <= (GETDATE()+6)  

Per una tabella contenente eventi, gli inserimenti potrebbero essere eseguiti molto prima della data dell'evento.For a table that contains events, inserts might be made well ahead of the event date. Se un mese prima è stato eseguito un inserimento per un evento della settimana successiva a quella corrente, senza che sia stata aggiornata la riga, quest'ultima non verrà replicata nel Sottoscrittore, anche se soddisfa il filtro di riga.If the insert for an event in the coming week was made a month ago and the row was not updated for another reason, the row is not replicated to the Subscriber even if it satisfies the row filter.

A seconda inoltre della configurazione della pubblicazione, la replica di tipo merge valuta i filtri in momenti diversi:In addition, depending on how the publication is configured, merge replication evaluates filters at different times:

  • Se una pubblicazione utilizza partizioni pre-calcolate, in base all'impostazione predefinita, i filtri vengono valutati ad ogni inserimento o aggiornamento di una riga.If a publication uses precomputed partitions (the default), filters are evaluated when a row is inserted or updated.

  • Se la pubblicazione non utilizza partizioni pre-calcolate, i filtri vengono valutati durante l'esecuzione dell'agente di merge.If the publication does not use precomputed partitions, filters are evaluated when the Merge Agent runs.

    Per altre informazioni sulle partizioni pre-calcolate, vedere Ottimizzare le prestazioni dei filtri con parametri con le partizioni pre-calcolate.For more information about precomputed partitions, see Optimize Parameterized Filter Performance with Precomputed Partitions. A seconda del momento in cui viene valutato il filtro, il tipo di dati che lo soddisfa sarà diverso.The time at which the filter is evaluated affects what data satisfies the filter. Se ad esempio una pubblicazione utilizza partizioni pre-calcolate e i dati vengono sincronizzati ogni due giorni, il subset di dati per il venditore potrebbe includere righe che risalgono fino a due giorni prima del previsto.For example, if a publication uses precomputed partitions, and you synchronize data every two days, the subset of data for the salesperson could include rows up to two days older than expected.

Indicazioni sull'utilizzo dei filtri di riga basati sul tempoRecommendations for Using Time-Based Row Filters

Il metodo seguente offre un approccio semplice ed efficace per il filtraggio basato sul tempo:The following method provides a robust and straightforward approach to filtering based on time:

  • Aggiungere alla tabella una colonna del tipo di dati bit.Add a column to the table of data type bit. Questa colonna indica se è necessario replicare una riga.This column is used to indicate whether a row should be replicated.

  • Utilizzare un filtro di riga che fa riferimento alla nuova colonna, anziché a una colonna basata sul tempo.Use a row filter that references the new column rather than a time-based column.

  • Creare un processo di SQL Server Agent, o un processo pianificato tramite un altro meccanismo, per aggiornare la colonna prima dell'avvio pianificato dell'agente di merge.Create a SQL Server Agent job (or a job scheduled through another mechanism) that updates the column before the Merge Agent is scheduled to run.

    Questo approccio consente di superare i limiti del metodo GETDATE() o di altri metodi basati sul tempo e di evitare il problema di determinare il momento della valutazione dei filtri per le partizioni.This approach addresses the shortcomings of using GETDATE() or another time-based method and avoids the problem of having to determine when filters are evaluated for partitions. Si consideri la tabella Events seguente:Consider the following example of an Events table:

EventIDEventID EventNameEventName EventCoordIDEventCoordID EventDateEventDate ReplicaReplicate
11 ReceptionReception 112112 2006-10-042006-10-04 11
22 PranzoDinner 112112 2006-10-102006-10-10 00
33 PartyParty 112112 2006-10-112006-10-11 00
44 MatrimonioWedding 112112 2006-10-122006-10-12 00

Il filtro di riga di questa tabella avrebbe quindi l'aspetto seguente:The row filter for this table would then look like this:

WHERE EventCoordID = CONVERT(INT,HOST_NAME()) AND Replicate = 1  

Il processo di SQL Server Agent può eseguire istruzioni Transact-SQLTransact-SQL simili alle seguenti prima dell'esecuzione di ogni agente di merge:The SQL Server Agent job could execute Transact-SQLTransact-SQL statements similar to the following before each Merge Agent run:

UPDATE Events SET Replicate = 0 WHERE Replicate = 1  
GO  
UPDATE Events SET Replicate = 1 WHERE EventDate <= GETDATE()+6  
GO  

La prima riga reimposta la colonna Replicate su 0, mentre la seconda riga imposta la colonna su 1 per gli eventi che avranno luogo nei sette giorni successivi.The first line resets the Replicate column to 0, and the second line sets the column to 1 for events that occur in the next seven days. Se questa istruzione Transact-SQLTransact-SQL viene eseguita il 07/10/2006, la tabella verrà aggiornata nel modo seguente:If this Transact-SQLTransact-SQL statement runs on 10/07/2006, the table is updated to:

EventIDEventID EventNameEventName EventCoordIDEventCoordID EventDateEventDate ReplicaReplicate
11 ReceptionReception 112112 2006-10-042006-10-04 00
22 PranzoDinner 112112 2006-10-102006-10-10 11
33 PartyParty 112112 2006-10-112006-10-11 11
44 MatrimonioWedding 112112 2006-10-122006-10-12 11

Gli eventi della settimana successiva sono ora contrassegnati come pronti per la replica.The events for the next week are now flagged as being ready to replicate. Alla successiva esecuzione dell'agente di merge per la sottoscrizione utilizzata dal coordinatore di eventi 112, le righe 2, 3 e 4 verranno scaricate nel Sottoscrittore e la riga 1 verrà rimossa dal Sottoscrittore.The next time the Merge Agent runs for the subscription that event coordinator 112 uses, rows 2, 3, and 4 will be downloaded to the Subscriber and row 1 will be removed from the Subscriber.

Vedere ancheSee Also

GETDATE (Transact-SQL) GETDATE (Transact-SQL)
Implementare processi Implement Jobs
Filtri di riga con parametri Parameterized Row Filters