项目需求:线上有一张表,数据类型为int类型,现在由于项目变更,需要这一列添加自增属性,而且,为了保证能尽快完成,希望使用脚本来实现,而不是在表设计中通过GUI窗口来实现。

  问题来了:SQL Server有类似于alter table的语法来直接修改表的列为自增列的吗?答案是:没有!那么,表设计中是如何实现的呢?

  创建一张测试表t1,然后使用SQL Server Profile来看看内部是怎么实现的。

   一、对现有的列添加自增属性

  步骤一:创建测试表t1

--表若存在,就删除
if(object_id('t1') is not null)
begin
drop table t1 ;
end ; --创建测试表
create table t1(id int, c1 char(10), c2 char(10)) ; --插入测试数据
insert into t1(id, c1, c2) values(1,'aaaaaaaaaa','bbb'),(10,'aaaaaaaaaa','bbb'),(100,'aaaaaaaaaa','bbb'),(1000,'aaaaaaaaaa','bbb');

  步骤二:开启SQL Server Profile(略)

  步骤三:打开表设计的GUI界面,修改为ID列为自增列(如下图红色框内所示),crtl+S保存一下

  

  步骤四:保存完成后,停止SQL Server Profile跟踪,查看SQL Server内部是怎么实现的

  总共是七步,详细步骤描述如下

--1、创建与原表表结构一致的临时表,并且在列上添加了自增属性
CREATE TABLE dbo.Tmp_t1
(
id int NOT NULL IDENTITY (10, 1),
c1 char(10) NULL,
c2 char(10) NULL
) ON [PRIMARY] --2、把新增临时表的锁升级为表锁
ALTER TABLE dbo.Tmp_t1 SET (LOCK_ESCALATION = TABLE) --3、设置新增临时表的自增列为可插入状态
SET IDENTITY_INSERT dbo.Tmp_t1 ON --4、把原表中的数据插入到临时表里
IF EXISTS(SELECT * FROM dbo.t1)
EXEC('INSERT INTO dbo.Tmp_t1 (id, c1, c2)
SELECT id, c1, c2 FROM dbo.t1 WITH (HOLDLOCK TABLOCKX)') --5、设置新增临时表的自增列为不可插入状态
SET IDENTITY_INSERT dbo.Tmp_t1 OFF --6、删除原表
DROP TABLE dbo.t1 --7、把临时表的表名修改为跟原表一致
EXECUTE sp_rename N'dbo.Tmp_t1', N't1', 'OBJECT'

  可见,SQL Server内部也是通过使用临时表作为中转来实现把列修改为自增列的,所以,如果真的需要用脚本而非GUI来实现修改为自增列,可以参考以上的7个步骤。

  注意:在设计中是修改了标识种子为10,所以在创建临时表Tmp_t1的时候出现了IDENTITY(10,1),如果没有修改标识种子,默认的是IDENTITY(1,1),可以在修改完成后使用以下语句进行修改

--修改自增列的标识种子
DBCC CHECKIDENT('t1', reseed, 100) ; --查看自增列的当前值
SELECT IDENT_CURRENT('t1')

  二、对现有的列删除自增属性

  步骤一:开启SQL Server Profile(略)

  步骤二、打开表设计的GUI界面,修改为ID列为非自增列(如下图红色框内所示),crtl+S保存一下

  

  步骤三、保存完成后,停止SQL Server Profile跟踪,查看SQL Server内部是怎么实现的

  

  总共是6步,详细描述如下

--创建临时表dbo.Tmp_t1
CREATE TABLE dbo.Tmp_t1
(
id int NOT NULL,
c1 varchar(20) NULL,
c2 varchar(20) NULL
) ON [PRIMARY] --锁定临时表,锁级别为表锁
ALTER TABLE dbo.Tmp_t1 SET (LOCK_ESCALATION = TABLE) --把原来的表的数据插入到临时表dbo.Tmp_t1
IF EXISTS(SELECT * FROM dbo.t1)
EXEC('INSERT INTO dbo.Tmp_t1 (id, c1, c2)
SELECT id, c1, c2 FROM dbo.t1 WITH (HOLDLOCK TABLOCKX)') --删除原表
DROP TABLE dbo.t1 --将临时表改名为原表
EXECUTE sp_rename N'dbo.Tmp_t1', N't1', 'OBJECT' --添加索引
ALTER TABLE dbo.t1 ADD CONSTRAINT
PK__t1__3213E83F7F60ED59 PRIMARY KEY CLUSTERED
(
id
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

  三、总结

  从以上的跟踪结果可以看出,在SQL Server对于现有表的列进行添加或者删除自增属性,都是通过临时表作为中转表来实现的

  以上,如有错谬,请不吝指正,万分感谢~~

SQL Server现有表上自增属性增删原理研究的更多相关文章

  1. 向SQL Server 现有表中添加新列并添加描述.

    注: sql server 2005 及以上支持. 版本估计是不支持(工作环境2005,2008). 工作需要, 需要向SQL Server 现有表中添加新列并添加描述. 从而有个如下存储过程. (先 ...

  2. sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)

    sql server 关于表中只增标识问题   由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...

  3. sql server 关于表中只增标识问题

    由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错误,不能修改 set identity_inse ...

  4. SQL Server数据库表重置自增主键号(通常是指ID)

    执行 DBCC CHECKIDENT ('table_name', NORESEED) 以确定列中的当前最大值 然后使用 DBCC CHECKIDENT ('table_name', RESEED,n ...

  5. [SQL]SQL Server数据表的基础知识与增查删改

    SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...

  6. 干货 | RDS For SQL Server单库上云

    数据库作为核心数据的重要存储,很多时候都会面临数据迁移的需求,例如:业务从本地迁移上云.数据中心故障需要切换至灾备中心.混合云或多云部署下的数据同步.流量突增导致数据库性能瓶颈需要拆分-- 本文将会一 ...

  7. SQL SERVER 数据库表同步复制 笔记

    SQL SERVER 数据库表同步复制 笔记 同步复制可运行在不同版本的SQL Server服务之间 环境模拟需要两台数据库192.168.1.1(发布),192.168.1.10(订阅) 1.在发布 ...

  8. 在SQL Server中对视图进行增删改

    原文:在SQL Server中对视图进行增删改 Lesktop开源IM发布以后,有一些网友问及如何在嵌入IM后与自己网站的用户系统整合(即如何让嵌入的IM直接使用网站原有的用户数据库,而不需要将已有的 ...

  9. Sql server 系统表

    sql server系统表详细说明 SQL Server 用户库中系统表说明 名称 说明 备注 syscolumns 每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行.   sys ...

随机推荐

  1. 【算法笔记】B1036 跟奥巴马一起编程

    1036 跟奥巴马一起编程 (15 分) 美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统.2014 年底,为庆祝“计算机科学教育周”正式启动,奥巴 ...

  2. HDU 6357.Hills And Valleys-动态规划(区间翻转l,r找最长非递减子序列)

    题意:给一串由n个数字组成的字符串,选择其中一个区间进行翻转,要求翻转后该字符串的最长非降子序列长度最长,输出这个最长非降子序列的长度以及翻转的区间的左右端点 #include<bits/std ...

  3. 事件获取目标 currentTarget target srcElement 三者之间的区别和联系

    currentTarget   指的是触发事件的当前对象,可以是冒泡和捕获的对象,不一定是点击或者鼠标移入等事件的直接触发对象.可以是他的父元素等. target 指的是事件触发的直接对象.IE有兼容 ...

  4. 坐标&接龙型动态规划 - 20181026

    109. Triangle 此题还可以用DFS,记忆化搜索去做,二刷实现 public class Solution { /** * @param triangle: a list of lists ...

  5. DataGuard具体搭建环节

    在上一篇blog中,详细介绍DataGuard实现的原理,本篇介绍DataGuard的具体搭建过程. 主库打开日志,并强制force logging SQL>shutdown immediate ...

  6. 迪米特法则(Law of Demeter)LoD

    using System; using System.Collections.Generic; using System.Text; namespace LawOfDemeter { //也叫Leas ...

  7. 安装Newton版Swift,配合keystone认证

    主控节点安装配置 Keystone 认证服务 主控节点 IP:192.168.81.11 yum install centos-release-openstack-newton -y yum upda ...

  8. 写些最近两个学安卓的笔记-关于Toast

    1.Toast可以在Activity和service里使用,在Service里使用时,Toast是显示在当前的Activity上. 2.Toast出现时,当前的Activity依然可见可交互. 3.T ...

  9. 安装cloudermanager时出现Acquiring installation lock问题(图文详解)

    不多说,直接上干货! 问题详情 解决办法 哪一个节点被锁就删除哪一个. 解决办法:进入/tmp 目录,ls -a查看,删除scm_prepare_node.*的文件,以及.scm_prepare_no ...

  10. Unity3D 发布成PC端常用设置

    本文,基于Unity 5.6pro版本来发布PC端.文中若有不妥之处,欢迎各位指出! 一.如何去掉Unity官方水印? 首先,你需要pro版本的Unity3D.如果,你是personal版本的话,就需 ...