Jeżeli zamierzasz wykonać procedurę składowaną pobierającą określone dane z jednej chwili, nie dopuszczając takiej opcji, że podczas wykonywania procedury ktoś dopisał/usunął czy też zmienił jakiś rekord możesz posłużyć się table hint TABLOCKX.
Poniższe zapytanie przed wykonaniem nałoży na tabelę blokadę na wyłączność. Skoro będzie blokada na wyłączność, to nikt nie może w tym czasie niczego zminiać. Wynik takiego zapytania na daną chwilę będzie więc jednoznaczny.
SELECT p.Size, AVG(p.ListPrice) FROM Production.Product AS p WITH (TABLOCKX) WHERE p.Color='Red' GROUP BY p.Size
TablockX blokuje tabelę, aż do zakończenia transakcji, w której znalazł się SELECT (sprawdzone)
Wskazówka zawierająca table hint znajduje się zawsze za nazwą tabeli (po aliasie, jeżeli go użyłeś). Wskazówki można ze sobą łączyć:
SELECT p.Size, AVG(p.ListPrice) FROM Production.Product AS p WITH (TABLOCKX, HOLDLOCK) WHERE p.Color='Red' GROUP BY p.Size
Nieco dziwnym hintem jest READPAST, który powoduje, że zapytanie opuszcza sobie rekordy zablokowane przez inne transakcje! Tak! Opuszcza sobie! Rozważ taki przykład:
Pierwsze okienko query:
SELECT * FROM Production.Product AS p WITH (READPAST) WHERE p.ProductID in (1,2,3,4)
Zostały zwrócone 4 rekordy.
A teraz drugie okienko query:
BEGIN TRANSACTION
UPDATE PRODUCTION.Product SET Name='1111' WHERE ProductID=3
Ta transakcja się jeszcze nie skończyła, więc rekord nr 3 ma blokadę na wyłączność
Wracamy do pierwszego okienka i ponawiamy zapytanie:
SELECT * FROM Production.Product AS p WITH (READPAST) WHERE p.ProductID in (1,2,3,4)
W wyniku otrzymujemy 3 rekordy:
Można by powiedzieć „i jak tu zaufać takiemu zapytaniu”. Możesz je wykorzystać jeżeli chcesz „na szybko”, „mniej więcej” sprawdzić zawartość tabel. Ale wypłaty na podstawie takiego zapytania nie chciałbym otrzymać…