SQL Server Sequence


What is sequence? SQL Server sequences allow you to store a sequence of numbers. You are in control of how that sequence operates. You control where it starts, where it ends and the quantity that the sequence is incremented by. It is similar to Identity and GUIDs. Sequences do not need to be put in any column or they can be put in many columns.

create sequence newTestSeq as int
start with 7
increment by 1
minvalue 1
maxvalue 9
cycle -- no cycle
--
select next value for newTestSeq as NextValue
-- Results after each SELECT
-- 7, 8, 9, 1, 2, 3, 4 ...
-- drop sequence newTestSeq

Notice that the cycle goes back to the minvalue, not the start value. You can have a look at the underlying table with the following. We will not show the result here.

select * from sys.sequences

If we decide not to set the minimum value then the minimum value will be the minimum value of the data type we are using, which will be about negative 4 billion if we are using INT. The start value will be about negative 4 billion, along with the start value. With INT, the maximum value will be the maximum value of the data type which is about 4 billion.

Using Sequence

How do we use sequence in practice? Let’s use an example of a table called [Names] that has only one column called [FirstName]. We already have a few rows in this table but we want to add another column to the table. We will add a new column called [NextNumer]. We will give it a default constraint of next value. Here is the code to do that.

alter table dbo.Names
add NextNumber int constraint DF_Names DEFAULT NEXT VALUE FOR newTestSeq

When we look at the table with a select statement we notice that the new column has NULL for each of the values in the new column.

Another Way

We could have created our column another way. Currently the column and constraint exits. Let’s back out of that. How do we do that? We need to drop the constraint, drop the column, add the column and then add the constraint. Here is the code that does that.

alter table Names drop DF_Names; -- drop constraint
alter table Names drop column NextNumber;  -- drop column

alter table Names add NextNumber int;  -- add column
alter table Names add constraint DF_Names default next value for newTestSeq for NextNumber -- add constraint

Insert a New Row

We will now insert a new row without providing any data for the new column we created called NextNumber.

begin tran
select * from Names;
insert into Names (FirstName) values ('Julie');
select * from Names;
rollback tran

Here is the screen shot in SSMS. The next number was 7 because we have previously experimented and ran it a few times. That’s okay for our test example.

What happens if we run the above code again? It rolls back the transaction of adding a new row. Does it roll back the sequence numbers?

No. The sequence itself does not get undone. You can see that it has gone up to 8.

Cannot Manually Update a System Catalog

SQL Server will not allow you to manually update the current_value of a sequence. If you try to run the following code you will get the error shown below that.

update sys.sequences set current_value = 2 where name = 'newTestSeq';
Msg 259, Level 16, State 1, Line 2
Ad hoc updates to system catalogs are not allowed.

Can Re-set a Sequence

While you cannot just manually update a sequence, you can alter it. What is the code for that? It is called re-setting. We use the syntax alter sequence MySeqName.

alter sequence newTestSeq restart with 1;
alter sequence newTestSeq increment by 2;
select next value for newTestSeq;
select next value for newTestSeq;

Here are the results in SSMS.

Existing NULL Values

What about the existing NULL values? Can we update them to a sequence number? We currently have three NULLs in our table.

select * from Names;  -- start withe all NULL in NextNumber
begin tran
update Names set NextNumber = next value for newTestSeq where FirstName = 'Sally';
select * from Names;
update Names set NextNumber = next value for newTestSeq;
select * from Names;
rollback tran
-- rollback does NOT re-set current number so do it here for our second example.
alter sequence newTestSeq restart with 1;  
select * from Names;  -- start withe all NULL in NextNumber
begin tran
update Names set NextNumber = next value for newTestSeq where FirstName = 'Sally';
select * from Names;
update Names set NextNumber = next value for newTestSeq where NextNumber is NULL;
select * from Names;
rollback tran

Here is the results in SSMS. Notice that we are using a WHERE clause with our update statement. Notice the values for Sally in the two examples. Also note that we can use where NextNumber is NULL. Using that where clause preserves the value that Sally had.