Αυτό υπάρχει στον SQL Server 2012 με τη μορφή των sequences. Σε παλαιότερες εκδόσεις υπάρχουν διάφορες τεχνικές για να δημιουργήσεις sequences και σίγουρα δεν υπάρχει λόγος να περιοριστείς μόνο σε ένα sequence.
Έτσι όπως είναι το procedure θα έχει θέμα με τα transactions.
- Αν δύο διαφορετικά transactions προσπαθήσουν να πάρουν νούμερο, το ένα από αυτά θα μπλοκάρει μέχρι να τελειώσει το δεύτερο, καθώς τα update locks που θα πάρει το ένα transaction θα διατηρηθούν μέχρι το τέλος.
- Επιπλέον, αν το transaction που κάνει rollback, θα επανέλθει το sequence στην προηγούμενη τιμή του με αποτέλεσμα ο επόμενος που θα ζητήσει νούμερο, να πάρει το ίδιο νούμερο ξανά.
Για να δουλέψει σωστά ένα sequence βασισμένο σε πίνακα θα πρέπει να εκτελείται ανεξάρτητα από το transaction που το περιβάλλει. Αυτό σημαίνει ότι ακόμα και αν κάνεις rollback, η τιμή του δεν θα επανέλθει σε κάποια προηγούμενη.
Αξίζει να ψάξεις άρθρα των Itzik Ben Gan, Aaron Bertrand για sequences καθώς προτείνουν διάφορες τεχνικές, με διαφορετικά πλεονεκτήματα και μειονεκτήματα η κάθε μία. Τα πράγματα βέβαια έχουν γίνει λίγο "περίεργα" καθώς τα πρώτα αποτελέσματα που θα βρεις πλέον αφορούν τα Sequences του SQL Server 2012 αντί για τα custom sequences των προηγούμενων εκδόσεων.
Τουλάχιστον μία τεχνική πάντως περιγράφεται στο Inside SQL Server 2008: T-SQL Programming και ευτυχώς μπορείς να την βρεις και στο Google Books. Δημιουργεί ένα πίνακα με Identity column και μετά σε ένα stored procedure κάνει save ένα savepoint, insert στον πίνακα και rollback το savepoint. ΤΟ αποτέλεσμα είναι ότι έχει πάρει ένα νέο νούμερο μέσω του SCOPE_IDENTITY() χωρίς να κάνει κάποια εγγραφή:
CREATE PROC dbo.GetSequence
@val as INT OUTPUT
AS
BEGIN TRAN
SAVE TRAN S1;
INSERT INTO dbo.Sequence DEFAULT VALUES;
SET @val=SCOPE_IDENTITY();
ROLLBACK TRAN S1;
COMMIT TRAN;
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos