quarta-feira, 1 de dezembro de 2010

Auto-incremento com o novo SEQUNCE no SQL Server 2011 Denali – Parte 1

Este artigo foi escrito utilizando o CTP de Novembro/2010 do SQL Server 2011 Denali.
O SQL Server code named “Denali” trás uma alternativa para a propriedade IDENTITY para o auto-incremento de valores, SEQUENCE. Para criar uma SEQUENCE temos o comando CREATE SEQUENCE, veja:

CREATE SEQUENCE Contador AS int
MINVALUE 1 NO MAXVALUE START WITH 1;

No comando acima foi criada uma SEQUENCE que inicia com o valor 1 e incremento de 1. Para testar execute o script abaixo:

SELECT NEXT VALUE FOR dbo.Contador as ClienteID
UNION ALL SELECT NEXT VALUE FOR dbo.Contador
UNION ALL SELECT NEXT VALUE FOR dbo.Contador
Resultado:
ClienteID
-----------
1
2
3
Para alterar o incremento para 5 basta utilizar o ALTER SEQUENCE e executar o mesmo SELECT acima para testar, veja:

ALTER SEQUENCE dbo.Contador RESTART WITH 1 INCREMENT BY 5;

SELECT NEXT VALUE FOR dbo.Contador as ClienteID
UNION ALL SELECT NEXT VALUE FOR dbo.Contador
UNION ALL SELECT NEXT VALUE FOR dbo.Contador
Resultado:
ClienteID
-----------
1
6
11
O SEQUENCE possui o mesmo comportamento do IDENTITY com relação a "gaps" na sequência de números gerados, no caso de ROLLBACK de uma transação, veja no exemplo abaixo:

ALTER SEQUENCE dbo.Contador RESTART WITH 1 INCREMENT BY 1;

BEGIN TRAN
SELECT NEXT VALUE FOR dbo.Contador as ProximoID;
ROLLBACK
SELECT ProximoID = NEXT VALUE FOR dbo.Contador;
O primeiro SELECT retorna 1 e o segundo 2, mesmo ocorrendo um ROLLBACK após o primeiro SELECT!

Quando utilizamos o IDENTITY temos a função IDENT_CURRENT() para retornar o valor corrente do IDENTITY em uma tabela, com o SEQUENCE execute o SELECT abaixo:

SELECT current_value FROM sys.sequences WHERE name = 'Contador'
Utilizar o SEQUENCE para gerar números seqüenciais automaticamente em uma tabela é muito simples veja:

CREATE SEQUENCE dbo.SEQ_Clientes AS int
MINVALUE 1 NO MAXVALUE START WITH 1;

CREATE TABLE dbo.Clientes
(ClienteID int not null DEFAULT NEXT VALUE FOR SEQ_Clientes,
Nome varchar(50) not null)
go
INSERT dbo.Clientes (Nome) VALUES ('Jose')
INSERT dbo.Clientes (Nome) VALUES ('Ana')
INSERT dbo.Clientes (Nome) VALUES ('Maria')

SELECT * FROM dbo.Clientes
Indicações de uso- A aplicação necessita saber o número antes de o INSERT ocorrer.
- A aplicação precisa compartilhar uma única numeração sequencial entre tabelas.
- Existe a necessidade de obter números seqüenciais (sem gap) para um conjunto de linhas (utilizar a Stored Procedure sp_sequence_get_range).

No próximo post farei uma comparação de desempenho entre IDENTITY e SEQUENCE,
Landry