(3.9)常用知识-标识值(identity)的不连续与强行插入、计算列

参考:深入了解identity

参考:深入了解计算列

概念:标识值 identity(begin,add_number) 是一种特殊的值,依赖于列,由sql server自动维护,是自增的,而且一般是不会重复的。但是sql server并不维护标识(identity)值的唯一(要保证其唯一需在使用列上添加主键或唯一约束),也不维护标识值的连续。

0、查看表是否有标识列

 select * from db_tank.sys.columns 
 where object_id=object_id('sys_users_detail') 
 AND is_identity=1

1、标识值不连续

(1)当事务回滚的时候

--构建测试表
create table test_1(id int identity(1,1)  ,col int)
GO
--构建测试数据
insert into test_1(col) values(101),(102),(103)
--事务回滚
begin tran a
    insert into test_1(col) values(104),(105),(106)
rollback tran a
--再次插入
insert into test_1(col) values(107),(108),(109)
--验证
select * from test_1


结果如下:
  

(2)删除记录

    无论被删除的标识值是最新添加的还是以前添加的,标识值均不会再回收利用,这里就不演示了。

(3)使用dbcc checkident重置标识值

USE tempdb;
go
--构建测试表
IF OBJECT_ID('test101')  IS NOT NULL
DROP TABLE test101

CREATE TABLE test101 (
id INT IDENTITY(1000,1), --起始从1000开始,补偿为1
num int 
)
INSERT INTO test101 VALUES(100)

--重置当前 identity增长值为 20000
dbcc checkident(test101,reseed,20000)
INSERT INTO test101 VALUES(1)

--重置后,新插入的变成20001了
SELECT * FROM test101

  

2、identity强行插入

  由于sql server不维护标识值的唯一,因此在没有主键、唯一约束等情况下,标识值可能会重复。

(1)使用 set identity_insert tableNmae on 强行插入标识值 (注意,用这种办法插入时,一定要写列名 而不是*)

    

(2)使用dbcc checkident重置标识~~1的(3)中已经描述过操作,这里不再赘述

3、在select into 中构造identity列

select 1 as id,2 as num,identity(int,1,1) rn into #temp1 

  

4、删除列的identity属性

--如何用sql语句去掉列的自增长(identity) 

--**无法通过alter把现有自增字段改为非自增 
--比如alter   table   a   alter   id   int,自增属性不会去掉 
--通过修改系统表可以做到(此法可能有不可预知的结果,慎之...) 

sp_configure   'allow   updates ',   1 
GO 
reconfigure   with   override 
GO 
update   syscolumns   set   colstat   =   colstat   &   0x0000   
where     id=object_id( '表名 ')   and   name= '字段名 ' 
GO 
sp_configure   'allow   updates ',   0 

--------------------------------------------- 
--折中的办法 
alter   table   a   add   xxx   int 
update   a   set   xxx=id 
alter   table   a   drop   column   id 
exec   sp_rename   'xxx ',   'id ',   'column ' 

 

 

5、计算列

  

CREATE TABLE #t
( 
x INT ,
y INT ,
z AS x+y
)

INSERT INTO #T VALUES(1,1);
INSERT INTO #T VALUES(2,1);
INSERT INTO #T VALUES(1,3);
INSERT INTO #T VALUES(4,4);
INSERT INTO #T VALUES(12,11);

SELECT * FROM #T

DROP TABLE #t

 

来一个比较实际的需求:弄一个日期加两位数流水号的自动编号


CREATE TABLE #t
(
id INT IDENTITY(1,1) ,
aa DATETIME DEFAULT GETDATE(),
new_id AS CONVERT(VARCHAR(20),GETDATE(),112)+'_'+RIGHT('0000000'+CAST(id AS VARCHAR(200)),3),
x INT
)

INSERT INTO #t (X) VALUES(1);
INSERT INTO #t (X) VALUES(1);
INSERT INTO #t (X) VALUES(1);
INSERT INTO #t (X) VALUES(1);

SELECT * FROM #T

DROP TABLE #T

 

  

 

 
posted @ 2018-06-06 18:13  郭大侠1  阅读(650)  评论(0编辑  收藏  举报