Sequence Objects

Loading

Sequence Objects in SQL Server: A Comprehensive Guide


1. Introduction to Sequence Objects

In SQL Server, a Sequence Object is a schema-bound object that generates a sequence of numeric values according to a specified specification. Unlike identity columns that are tied to a specific table and cannot be reused or altered easily, sequences are independent and can be used across multiple tables or operations. Sequence objects provide a more flexible and robust way to generate unique numbers, especially when dealing with concurrent operations, such as in multi-table inserts, and are frequently used to generate unique identifiers for tables, keys, and other database objects.

This guide will provide a deep dive into sequence objects in SQL Server, covering their creation, usage, and advanced features such as caching, cycling, and performance considerations.


2. Basics of Sequence Objects

2.1. What is a Sequence?

A sequence object in SQL Server generates a sequence of numeric values according to the specification provided at the time of creation. These numbers are generally used as primary keys or unique identifiers for rows in tables. A sequence can generate numbers in either ascending or descending order, and you can define the step between the numbers, starting point, and maximum or minimum values.

2.2. Why Use Sequence Objects?

  • Independent of Tables: Unlike identity columns, sequences are independent objects that can be used across different tables or even different sessions. This gives greater flexibility when generating unique values.
  • Customizable: You have control over the starting value, increment value, minimum and maximum values, and the cycle behavior of the sequence.
  • Performance: Sequences allow you to generate numbers without requiring locks or other performance-degrading mechanisms, which makes them more efficient in multi-threaded or high-transaction environments.
  • Reusability: A sequence can be reused to generate values for multiple columns or tables.

2.3. Creating a Sequence

To create a sequence, use the CREATE SEQUENCE statement. Here is a simple example:

CREATE SEQUENCE seq_example
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 1000000
    CYCLE;

In this example, the sequence starts at 1, increments by 1, and cycles back to 1 when the maximum value is reached.

  • START WITH: Specifies the initial value of the sequence.
  • INCREMENT BY: Defines the increment between each value generated by the sequence.
  • MINVALUE and MAXVALUE: Set the range of numbers that the sequence can generate.
  • CYCLE: Specifies that the sequence should restart from the minimum value once the maximum value is reached.

3. Sequence Object Options and Properties

When creating a sequence, several options and properties allow you to customize its behavior:

3.1. START WITH

This specifies the initial value from which the sequence will begin generating numbers.

Example:

CREATE SEQUENCE seq_example
    START WITH 1000;

This will make the first value of the sequence 1000.

3.2. INCREMENT BY

This defines the step size for generating subsequent numbers in the sequence. By default, it is set to 1, but you can change it to any positive or negative integer.

Example:

CREATE SEQUENCE seq_example
    INCREMENT BY 5;

In this case, the sequence will generate numbers that increment by 5 (e.g., 1000, 1005, 1010, and so on).

3.3. MINVALUE and MAXVALUE

These parameters define the lower and upper bounds for the sequence. You can specify a minimum and maximum value, and the sequence will stop generating numbers when the boundary is reached unless the CYCLE option is enabled.

Example:

CREATE SEQUENCE seq_example
    MINVALUE 1000
    MAXVALUE 9999;

This sequence will not generate values below 1000 or above 9999, unless CYCLE is specified.

3.4. CYCLE

If CYCLE is specified, the sequence will restart when it reaches the MAXVALUE or MINVALUE. Without CYCLE, SQL Server will throw an error when the sequence reaches its boundary.

Example:

CREATE SEQUENCE seq_example
    CYCLE;

When the sequence reaches the MAXVALUE, it will cycle back to the MINVALUE and continue.

3.5. CACHE and NO CACHE

The CACHE option is used to enhance performance by storing a specified number of sequence values in memory. This reduces the need to access the sequence object on disk, thereby improving performance for applications that frequently request values.

CREATE SEQUENCE seq_example
    CACHE 10;

With this, SQL Server will pre-generate and cache the next 10 sequence numbers in memory. However, if the server is restarted, the cached values are lost, and the sequence continues from the next available value.

Alternatively, NO CACHE ensures that sequence numbers are always generated on demand without caching, which can have a performance overhead.

CREATE SEQUENCE seq_example
    NO CACHE;

3.6. ORDER

The ORDER option ensures that sequence numbers are generated in the exact order they are requested, which is critical in certain applications, such as when the sequence is used in conjunction with high-transaction systems. By default, sequence objects use an unordered allocation method for efficiency.

Example:

CREATE SEQUENCE seq_example
    ORDER;

4. Using Sequence Objects

Once a sequence object is created, it can be used to generate sequence values. These values can be retrieved using the NEXT VALUE FOR expression.

4.1. Retrieving Sequence Values

You can retrieve the next value from a sequence using the NEXT VALUE FOR clause in your SQL statements.

SELECT NEXT VALUE FOR seq_example AS NewValue;

This query retrieves the next value from the seq_example sequence.

4.2. Using Sequences in INSERT Statements

Sequences are typically used in INSERT statements for generating unique values for columns, particularly primary keys.

INSERT INTO Employees (EmployeeID, EmployeeName)
VALUES (NEXT VALUE FOR seq_example, 'John Doe');

In this example, the EmployeeID is generated from the seq_example sequence, ensuring each employee has a unique identifier.

4.3. Sequences in Multi-Row Inserts

Sequences can be used in multi-row insert statements to provide unique values for each row:

INSERT INTO Orders (OrderID, OrderDate)
VALUES 
    (NEXT VALUE FOR seq_example, '2025-04-01'),
    (NEXT VALUE FOR seq_example, '2025-04-02'),
    (NEXT VALUE FOR seq_example, '2025-04-03');

Each order will get a unique OrderID generated by the sequence.


5. Managing Sequence Objects

SQL Server provides various commands for managing sequence objects, such as altering, dropping, and viewing the current state of sequences.

5.1. Altering a Sequence

If you need to change the properties of a sequence (e.g., change the increment value or starting point), you can use the ALTER SEQUENCE statement.

ALTER SEQUENCE seq_example
    RESTART WITH 2000
    INCREMENT BY 10;

This changes the starting value to 2000 and the increment to 10.

5.2. Dropping a Sequence

To remove a sequence object, use the DROP SEQUENCE command. This will remove the sequence from the database.

DROP SEQUENCE seq_example;

5.3. Viewing Sequence Information

You can view the properties and current value of a sequence using the sys.sequences system catalog view.

SELECT * FROM sys.sequences
WHERE name = 'seq_example';

This query provides details such as the current value, minimum and maximum values, and increment of the sequence.


6. Advanced Usage of Sequences

6.1. Sequence for Auditing

One interesting use of sequences is in auditing. By using a sequence object to generate a unique audit ID, you can track each transaction with a globally unique identifier.

CREATE SEQUENCE AuditIDSeq
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 1000000
    NO CYCLE;

You can then use this sequence in your audit table:

INSERT INTO AuditLogs (AuditID, Action, ActionDate)
VALUES (NEXT VALUE FOR AuditIDSeq, 'User login', GETDATE());

6.2. Sequence for Global Identifiers

Sequences can also be used for generating global unique identifiers (GUIDs) for distributed systems. They allow multiple servers or applications to generate unique values independently, without worrying about conflicts.

6.3. Sequences with Transactions

Sequences can be used inside transactions, but one important consideration is that they are not rolled back when a transaction is rolled back. Once a sequence value is generated, it cannot be undone.

BEGIN TRANSACTION;
INSERT INTO Orders (OrderID, OrderDate)
VALUES (NEXT VALUE FOR seq_example, '2025-04-01');
-- If the transaction is rolled back, the sequence value is not rolled back.
ROLLBACK;

7. Performance Considerations

7.1. Sequence Caching

Caching sequence numbers can provide significant performance improvements. However, it’s important to choose an appropriate cache size. Too large a cache can waste memory, and too small a cache can lead to frequent disk reads.

7.2. Sequence in High-Concurrency Environments

Sequences are designed to be thread-safe and can be used in high-concurrency environments. SQL Server uses an optimized algorithm to generate sequence numbers, ensuring minimal contention and improved performance even when many users are accessing the sequence concurrently.

7.3. Performance Impact of CYCLE

The CYCLE option allows sequences to wrap around after reaching the maximum or minimum value. While this is useful in certain scenarios, be mindful of the potential for wrapping errors or unintended behavior if your application doesn’t handle it properly.


Sequence objects in SQL Server are a powerful feature that offers flexibility, performance, and simplicity for generating unique numeric values. Unlike identity columns, sequences are independent objects that can be reused across tables and sessions, providing more control over the generated values. With the ability to customize increments, cycle behavior, and caching, sequences are ideal for applications that require globally unique identifiers, high concurrency, and efficient number generation.

While sequences provide significant advantages over traditional identity columns, it’s important to understand their limitations and best practices. By properly leveraging sequence objects, you can improve both the performance and flexibility of your database design, especially when dealing with distributed systems and high-volume applications.

Leave a Reply

Your email address will not be published. Required fields are marked *