SQL Server 序列(SEQUENCE)使用

众所周知,在之前的SQL SERVER版本中,一般采用GUID或者IDENTITY来作为标示符,但是IDENTITY是一个表对象,只能保证在一张表里面的序列,当我们遇到以下情况时,

如上表,我们需要在多表之间,实现ID的一致性,在SQL SERVER里面就会有一定的麻烦,通常我们会使用额外使用一张TEMP表来映射这些ID的关系然后再从中取序列来完成。

SEQUENCE在ORACLE中其实很早就存在了,SQL SERVER 2012的SEQUENCE功能和那个相似,是一个基于SCHEMA的对象,所以可以被多表调用。

序列是用户定义的绑定到架构的对象,该对象可根据创建序列所依据的规范来生成数值序列。 这组数值以定义的间隔按升序或降序生成,并且可配置为用尽时重新启动(循环)。 序列不与特定表相关联,这一点与标识列不同。 应用程序将引用某一序列对象以便检索其下一个值。 序列与表之间的关系由应用程序控制。 用户应用程序可以引用一个序列对象,并跨多个行和表协调值。与在插入行时生成的标识列值不同,应用程序可以获得下一个序列号,而不必通过调用 NEXT VALUE FOR 函数来插入行。 使用 sp_sequence_get_range 同时获取多个序列号。


SEQUENCE语法如下: (创建一个序列对象并指定其属性)

CREATE SEQUENCE [schema_name . ] sequence_name  
    [ AS [ built_in_integer_type | user-defined_integer_type ] ]  
    [ START WITH <constant> ]  
    [ INCREMENT BY <constant> ]  
    [ { MINVALUE [ <constant> ] } | { NO MINVALUE } ]  
    [ { MAXVALUE [ <constant> ] } | { NO MAXVALUE } ]  
    [ CYCLE | { NO CYCLE } ]  
    [ { CACHE [ <constant> ] } | { NO CACHE } ]  
    [ ; ]  

sequence_name 指定数据库中标识序列的唯一名称。 类型为 sysname。
[ built_in_integer_type | user-defined_integer_type 序列可定义为任何整数类型。如果未提供任何数据类型,则默认 bigint类型。
START WITH 序列对象返回的第一个值。 START 值必须小于或等于序列对象的最大值并大于或等于其最小值。
INCREMENT BY 每次调用 NEXT VALUE FOR 函数时序列对象值递增(如果为负数,则为递减)的值。
MIN和MAX 分别设置最小和最大值
CYCLE 设置是否循环,默认循环选项是 NO CYCLE
CACHE 通过最大限度地减少生成序列编号所需的磁盘 IO 数,可以提高使用序列对象的应用程序的性能。 默认值为 CACHE。

ORACLE中有SEQUENCE的功能,SQL SERVER类似的功能使用IDENTITY列实现,但是有很大的局限性。在2012中,微软终于增加了 SEQUENCE 对象,功能和性能都有了很大的提高。
我们可以在SSMS中创建也可以使用SQL SERVER脚本创建序列对象:

 

使用SQL创建序列对象:

IF EXISTS(SELECT * FROM sys.sequences WHERE name = N'TestSeq')
    DROP SEQUENCE TestSeq;
GO
--创建序列对象 
CREATE SEQUENCE TestSeq AS TINYINT
    START WITH 1
    INCREMENT BY 1;
GO
--创建表
CREATE TABLE TEST(ID tinyint,  Name varchar(150))
--产生序列号码并插入表中
INSERT INTO TEST(ID,Name) VALUES(NEXT VALUE FOR TestSeq, 'allen')
INSERT INTO TEST(ID,Name) VALUES(NEXT VALUE FOR TestSeq, 'kevin')
 
SELECT * FROM TEST

 

--产生序列可以重复使用,下面的例子当序列号码超过255后又重新从0开始。
CREATE SEQUENCE [dbo].[Test1Seq] AS [tinyint]
  START WITH 0
  INCREMENT BY 5
  CYCLE
 
SELECT NEXT VALUE FOR [Test1Seq]

 

--重新将序列初始值变为5
ALTER SEQUENCE dbo.TestSeq RESTART WITH 5;
 
SELECT * FROM sys.sequences WHERE name = 'TestSeq'

 

--共享序列,两个表可以使用同一个序列对象(IDENTITY列是不可以的) 
CREATE SEQUENCE dbo.Seq AS INT
   START WITH 1
   INCREMENT BY 1
 
CREATE TABLE dbo.Examp1
 (
   Seq INT NOT NULL,
   Name VARCHAR(50) NOT NULL
 );
 
CREATE TABLE dbo.Examp2
 (
   Seq INT NOT NULL,
   Name VARCHAR(50)NOTNULL 
 );
  
INSERT INTO dbo.Examp1(Seq,Name) VALUES (NEXT VALUE FOR dbo.Seq, 'Tom');
INSERT INTO dbo.Examp2(Seq,Name) VALUES (NEXT VALUE FOR dbo.Seq, 'Jerry');
 
SELECT * FROM Examp1
SELECT * FROM Examp2

 

--可以直接在查询中使用序列对象(IDENTITY列是不可以的)
CREATE SEQUENCE SeqOrder AS tinyint
    START WITH1
    INCREMENT BY1
    MINVALUE 1
    NO MAXVALUE
    CYCLE;
GO
 
SELECT ID, Name,NEXT VALUE FOR SeqOrder OVER(ORDER BY Name DESC) AS [Order] FROM test;

 

为了提升性能,还可以使用CACHE选项,这样就可以将序列号码缓存到内存,减少IO操作,值得一提的是序列对象可以指定最大值和最小值,增加值可以为负数

原文地址:https://www.cnblogs.com/zhaoshujie/p/10146138.html