使用IDENTITY列属性和Sequence对象

使用IDENTITY列属性

1. 建立表 Sales.MyOrders

USE TSQL2012;
IF OBJECT_ID(N'Sales.MyOrders', N'U') IS NOT NULL DROP TABLE Sales.MyOrders;
GO

CREATE TABLE Sales.MyOrders
(
  orderid INT NOT NULL IDENTITY(1, 1)
    CONSTRAINT PK_MyOrders_orderid PRIMARY KEY,
  custid  INT NOT NULL
    CONSTRAINT CHK_MyOrders_custid CHECK(custid > 0),
  empid   INT NOT NULL
    CONSTRAINT CHK_MyOrders_empid CHECK(empid > 0),
  orderdate DATE NOT NULL
);

2. 插入一些记录

INSERT  INTO Sales.MyOrders
        ( custid, empid, orderdate )
VALUES  ( 1, 2, '20120620' ),
        ( 1, 3, '20120620' ),
        ( 2, 2, '20120620' );

3. IDENTITY 相关函数

SELECT
  SCOPE_IDENTITY()                AS SCOPE_IDENTITY, /*返回插入到同一作用域中的标识列内的最后一个标识值。  
                                                      一个范围是一个模块:存储过程、触发器、函数或批处理。
                                                      因此,如果两个语句处于同一个存储过程、函数或批处理中,则它们位于相同的作用域中。 */
  @@IDENTITY                      AS [@@IDENTITY], --与上面一样返回同一作用域内的最后一个标示符,但是不限作用域。
  IDENT_CURRENT('Sales.MyOrders') AS IDENT_CURRENT; --返回为指定的表或视图生成的最后一个标识值。

4. 如果Truncate 表,该表的IDENTITY的值就会重置,仅仅删除记录不会。

TRUNCATE TABLE Sales.MyOrders;

SELECT IDENT_CURRENT('Sales.MyOrders') AS [IDENT_CURRENT];

5. 使用DBCC CHECKINDENT 续种

DBCC CHECKIDENT('Sales.MyOrders', RESEED, 4);

INSERT INTO Sales.MyOrders(custid, empid, orderdate) VALUES(2, 2, '20120620');
SELECT * FROM Sales.MyOrders;

 

使用Sequence 对象

SQL Server 2012起引入了新的数据库对象 sequence,它不像IDENTITY 列属性有那么多限制(比如 IDENTITY 属性只能应用在某个表的某一列。 有时候你希望多个表的key没有冲突,但是IDENTITY无法跨表操作。你希望先生成一个值再使用,也不行。 你无法更新IDENTITY列。   IDENTITY 无法循环使用。 Truncate 会重置 IDENTITY值 )

1. 创建sequence

-- create sequence
IF OBJECT_ID(N'Sales.SeqOrderIDs', N'SO') IS NOT NULL DROP SEQUENCE Sales.SeqOrderIDs;

--部分参数
--INCREMENT BY   增量值,默认为1
--MINVALUE 最小值,默认为数据类型的最小值,比如INT的最小值为 -2147483648
--MAXVALUE 最大值,默认值为数据类型的最大值
--CYCLE|NO CYCLE 是否循环,默认为不循环
--START WITH ,设置一个起始值,默认起始值是升序序列对象的最小值和降序序列对象的最大值。
CREATE SEQUENCE Sales.SeqOrderIDs AS INT
  MINVALUE 1
  CYCLE;

2. 查询系统中的sequence

SELECT  TYPE_NAME(system_type_id) AS type ,
        start_value ,
        minimum_value ,
        current_value ,
        increment ,
        is_cycling
FROM    sys.sequences
WHERE   object_id = OBJECT_ID(N'Sales.SeqOrderIDs', N'SO');

3. 获取一个新值

-- request a new value; 
SELECT NEXT VALUE FOR Sales.SeqOrderIDs;

4. 序列的所有属性都可以通过ALTER SEQUENCE命令修改。比如更改当前值

ALTER SEQUENCE Sales.SeqOrderIDs
  RESTART WITH 1;

5. 实际运用

  a)  创建Sales.MyOrders 表并插入数据

-- recreate Sales.MyOrders table
IF OBJECT_ID(N'Sales.MyOrders', N'U') IS NOT NULL DROP TABLE Sales.MyOrders;
GO

CREATE TABLE Sales.MyOrders
(
  orderid INT NOT NULL
    CONSTRAINT PK_MyOrders_orderid PRIMARY KEY,
  custid  INT NOT NULL
    CONSTRAINT CHK_MyOrders_custid CHECK(custid > 0),
  empid   INT NOT NULL
    CONSTRAINT CHK_MyOrders_empid CHECK(empid > 0),
  orderdate DATE NOT NULL
);

-- use in INSERT VALUES
INSERT INTO Sales.MyOrders(orderid, custid, empid, orderdate) VALUES
  (NEXT VALUE FOR Sales.SeqOrderIDs, 1, 2, '20120620'),
  (NEXT VALUE FOR Sales.SeqOrderIDs, 1, 3, '20120620'),
  (NEXT VALUE FOR Sales.SeqOrderIDs, 2, 2, '20120620');

-- use in INSERT SELECT
INSERT INTO Sales.MyOrders(orderid, custid, empid, orderdate)
  SELECT
    NEXT VALUE FOR Sales.SeqOrderIDs OVER(ORDER BY orderid),
    custid, empid, orderdate
  FROM Sales.Orders
  WHERE custid = 1;

b) 直接把sequence设为default约束

ALTER TABLE Sales.MyOrders
  ADD CONSTRAINT DFT_MyOrders_orderid
    DEFAULT(NEXT VALUE FOR Sales.SeqOrderIDs) FOR orderid;

测试

INSERT INTO Sales.MyOrders(custid, empid, orderdate)
  SELECT
    custid, empid, orderdate
  FROM Sales.Orders
  WHERE custid = 2;

 

参考文档

SCOPE_IDENTITY (Transact-SQL)

https://msdn.microsoft.com/zh-cn/library/ms190315.aspx

@@IDENTITY (Transact-SQL)

https://msdn.microsoft.com/zh-cn/library/ms187342.aspx

IDENT_CURRENT (Transact-SQL)

https://msdn.microsoft.com/library/ms175098.aspx

CREATE SEQUENCE (Transact-SQL)

https://msdn.microsoft.com/zh-cn/library/ff878091.aspx

posted @ 2015-03-10 23:13  Haseo  阅读(1582)  评论(0编辑  收藏  举报