加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_宿迁站长网 (https://www.0527zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

序列号

发布时间:2022-10-18 19:03:56 所属栏目:MsSql教程 来源:未知
导读: 序列号本文内容
适用于:

SQL Server(所有受支持的版本)

Azure SQL 数据库

Azure SQL 托管实例
序列是一种用户定义的架构绑定对象,它根据创建该序列时采用的规范生成一组数值。 这组

序列号本文内容

适用于:

SQL Server(所有受支持的版本)

Azure SQL 数据库

Azure SQL 托管实例

序列是一种用户定义的架构绑定对象,它根据创建该序列时采用的规范生成一组数值。 这组数值以定义的间隔按升序或降序生成,并且可根据要求循环(重复)。 序列不与表相关联,这一点与标识列不同。 应用程序将引用某一序列对象以便接收其下一个值。 序列与表之间的关系由应用程序控制。 用户应用程序可以引用某一序列对象并且跨多行和表协调值键。

序列是通过使用 CREATE SEQUENCE 语句独立于表来创建的。 其选项使您可以控制增量、最大值和最小值、起始点、自动重新开始功能和缓存以便改进性能。 有关这些选项的信息,请参阅 CREATE SEQUENCE。

与在插入行时生成的标识列值不同,应用程序可以通过调用 NEXT VALUE FOR 函数在插入行之前获取下一序列号。 在调用 NEXT VALUE FOR 时分配该序列号,即使在该序列号永远也不插入某个表中时也是如此。 此 NEXT VALUE FOR 函数可用作表定义中某个列的默认值。 使用 sp_sequence_get_range 可一次获取某个范围的多个序列号。

序列可定义为任何整数数据类型。 如果未指定数据类型,则序列将默认为 bigint。

使用序列

在以下情况下将使用序列,而非标识列:

限制

与不能更改其值的标识列不同,在插入到表后不自动保护序列值。 若要防止更改序列值,请对表使用更新触发器以便回滚更改。

对于序列值不自动强制唯一性。 按照设计能够重复使用序列值。 如果某个表中的序列值要求唯一,则对列创建唯一索引。 如果要求表中的序列值在一组表之间唯一,则创建触发器以免更新语句或序列号循环导致的重复项。

序列对象根据其定义生成数值,但序列对象不控制生成数值的方式。 在回滚事务时、在某个序列对象由多个表共享时或者在分配序列号且不在多个表中使用它们时,插入到表中的序列号可能具有间断。 当使用 CACHE 选项创建时,意外关机(如电源故障)可能导致缓存中的序列号丢失。

如果在单个 Transact-SQL 语句中有多个 NEXT VALUE FOR 函数实例指定相同的序列生成器,那么所有这些实例将为该 Transact-SQL 语句处理的给定行返回相同的值。 此行为与 ANSI 标准保持一致。

序列号在当前事务的作用域之外生成。 无论提交还是回滚使用序列号的事务,都会占用序列号。 只有在记录被完全填充后,才会发生重复验证。 在某些情况下,这可能会导致在创建过程中将相同数字用于多个记录,但随后被识别为重复。 如果发生这种情况,且其他自动编号值已应用于后续记录,这可能会导致自动编号值之间存在差距。

典型用法

若要创建从 -2,147,483,648 到 2,147,483,647 且增量为 1 的整数序列号,请使用以下语句。

CREATE SEQUENCE Schema.SequenceName  
    AS int  
    INCREMENT BY 1 ;  

若要创建类似于从 1 到 2,147,483,647 且增量为 1 的标识列的整数序列号,请使用以下语句。

CREATE SEQUENCE Schema.SequenceName  
    AS int  
    START WITH 1  
    INCREMENT BY 1 ;  
  

管理序列

有关序列的信息,请查询 sys.sequences。

示例

请在 CREATE SEQUENCE (Transact-SQL)、NEXT VALUE FOR (Transact-SQL) 和 sp_sequence_get_range 主题查看其他示例。

A. 在单个表中使用序列号

下面的示例创建一个名为 Test 的架构、一个名为 Orders 的表以及一个名为 CountBy1 的序列mssql 使用序列,然后使用 NEXT VALUE FOR 函数将行插入到该表中。

--Create the Test schema  
CREATE SCHEMA Test ;  
GO  
  
-- Create a table  
CREATE TABLE Test.Orders  
    (OrderID int PRIMARY KEY,  
    Name varchar(20) NOT NULL,  
    Qty int NOT NULL);  
GO  
  
-- Create a sequence  
CREATE SEQUENCE Test.CountBy1  
    START WITH 1  
    INCREMENT BY 1 ;  
GO  
  
-- Insert three records  
INSERT Test.Orders (OrderID, Name, Qty)  
    VALUES (NEXT VALUE FOR Test.CountBy1, 'Tire', 2) ;  
INSERT test.Orders (OrderID, Name, Qty)  
    VALUES (NEXT VALUE FOR Test.CountBy1, 'Seat', 1) ;  
INSERT test.Orders (OrderID, Name, Qty)  
    VALUES (NEXT VALUE FOR Test.CountBy1, 'Brake', 1) ;  
GO  
  
-- View the table  
SELECT * FROM Test.Orders ;  
GO  

下面是结果集:

OrderID Name Qty

1Tire 2

2Seat 1

3Brake 1

B. 在插入某一行之前调用 NEXT VALUE FOR

下面的示例通过使用在示例 A 中创建的 Orders 表,声明一个名为 @nextID的变量,然后使用 NEXT VALUE FOR 函数将该变量设置为下一个可用的序列号。 假定应用程序对订单执行某种处理,例如向客户提供其潜在订单的 OrderID 号,然后验证该订单。 无论这一处理时间有多长,或者在这个处理过程中添加了多少其他订单,原始编号都保留供此连接使用。 最后, INSERT 语句将该订单添加到 Orders 表。

DECLARE @NextID int ;  
SET @NextID = NEXT VALUE FOR Test.CountBy1;  
-- Some work happens  
INSERT Test.Orders (OrderID, Name, Qty)  
    VALUES (@NextID, 'Rim', 2) ;  
GO  
  

C. 在多个表中使用序列号

此示例假定一个生产线监视进程接收在车间中发生的事件的通知。 每个事件都接收一个唯一且单调递增的 EventID 号。 所有事件都使用相同的 EventID 序列号,因此,汇总了所有事件的报表可唯一标识各事件。 但是,事件数据根据事件的类型存储于三个不同的表中。 该代码示例创建一个名为 Audit的架构、一个名为 EventCounter的序列以及三个表,这三个表都使用 EventCounter 序列作为默认值。 然后,该示例向这三个表添加行并且查询结果。

CREATE SCHEMA Audit ;  
GO  
CREATE SEQUENCE Audit.EventCounter  
    AS int  
    START WITH 1  
    INCREMENT BY 1 ;  
GO  
  
CREATE TABLE Audit.ProcessEvents  
(  
    EventID int PRIMARY KEY CLUSTERED   
        DEFAULT (NEXT VALUE FOR Audit.EventCounter),  
    EventTime datetime NOT NULL DEFAULT (getdate()),  
    EventCode nvarchar(5) NOT NULL,  
    Description nvarchar(300) NULL  
) ;  
GO  
  
CREATE TABLE Audit.ErrorEvents  
(  
    EventID int PRIMARY KEY CLUSTERED  
        DEFAULT (NEXT VALUE FOR Audit.EventCounter),  
    EventTime datetime NOT NULL DEFAULT (getdate()),  
    EquipmentID int NULL,  
    ErrorNumber int NOT NULL,  
    EventDesc nvarchar(256) NULL  
) ;  
GO  
  
CREATE TABLE Audit.StartStopEvents  
(  
    EventID int PRIMARY KEY CLUSTERED  
        DEFAULT (NEXT VALUE FOR Audit.EventCounter),  
    EventTime datetime NOT NULL DEFAULT (getdate()),  
    EquipmentID int NOT NULL,  
    StartOrStop bit NOT NULL  
) ;  
GO  
  
INSERT Audit.StartStopEvents (EquipmentID, StartOrStop)   
    VALUES (248, 0) ;  
INSERT Audit.StartStopEvents (EquipmentID, StartOrStop)   
    VALUES (72, 0) ;  
INSERT Audit.ProcessEvents (EventCode, Description)   
    VALUES (2735,   
    'Clean room temperature 18 degrees C.') ;  
INSERT Audit.ProcessEvents (EventCode, Description)   
    VALUES (18, 'Spin rate threashold exceeded.') ;  
INSERT Audit.ErrorEvents (EquipmentID, ErrorNumber, EventDesc)   
    VALUES (248, 82, 'Feeder jam') ;  
INSERT Audit.StartStopEvents (EquipmentID, StartOrStop)   
    VALUES (248, 1) ;  
INSERT Audit.ProcessEvents (EventCode, Description)   
    VALUES (1841, 'Central feed in bypass mode.') ;  
-- The following statement combines all events, though not all fields.  
SELECT EventID, EventTime, Description FROM Audit.ProcessEvents   
UNION SELECT EventID, EventTime, EventDesc FROM Audit.ErrorEvents   
UNION SELECT EventID, EventTime,   
CASE StartOrStop   
    WHEN 0 THEN 'Start'   
    ELSE 'Stop'  
END   
FROM Audit.StartStopEvents  
ORDER BY EventID ;  
GO  
  

下面是结果集。

EventID EventTimeDescription

(编辑:云计算网_宿迁站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!