客户需求:修改一张表的结构,并保留里面的数据。
解决方案:
- 修改表名
- 用原表名创建一个新的表
- 用脚本把原表数据迁移到新表中
- 删除原表
具体实现:
-
修改表名:把表Customer重命名为Customer_REN
EXEC sp_rename 'Customer','Customer_REN'
执行完后会有如下警告:Caution: Changing any part of an object name could break scripts and stored procedures.
如果现有查询、视图、用户定义函数、存储过程引用该表,则更改表名将使这些对象无效。当然我们后来会添加一个新的Customer表,但如果原表中的字段有删除或更改,一样会影响到视图、用户定义函数、存储过程,所以要注意检查。
更改表后最好删除外键,因为后面添加新的Customer表后添加外键约束时,外键名称可能会冲突。
查询外键:以下SQL语句就可以查询出Customer_REN表下的所有外键名称。
SELECT name from sys.foreign_key_columns f join sys.objects o on f.constraint_object_id=o.object_id WHERE f.parent_object_id=object_id('Customer_REN')
删除外键:ALTER TABLE Customer_REN DROP CONSTRAINT 外键名称
-
用原表名创建一个新的表
在SQL Server Manager Studio中设计好一张表后,右键表名 > Script Table as > CREATE To > New Query Editor Window就可以把创建该表的脚本生成出来,注意检查生成的脚本,里面包含了数据库名称,如果你只是向客户提供脚本去他的数据库上运行,你们的数据库名可能会不一样,这样就需要把脚本里面的数据库名删除。
-
用脚本把原表中的数据导入到新表中
INSERT INTO Customer(Field1,Field2,...)
SELECT Field1,Field2,....
FROM Customer_REN如果新表中添加了新的外键约束,迁移数据往往会碰到脏数据导致数据迁移失败,下面简单介绍一下如何删除脏数据( dirty data )。
这里的脏数据是指你需要导入的数据在外键关联的另一张表中没有对应的数据,那么你这条数据就是脏数据,是不允许被插入进去的,需要删除。
首先查询出脏数据:
SELECT *
FROM Customer AS c
LEFT JOIN Person AS p
ON c.PersonGuid = p.PersonGuid
WHERE p.PersonGuid IS NULL这样就可以查询出Customer中的脏数据了,接下来就是删除脏数据,删除脏数据分两种情况:
如果Customer中的PersonGuid是个非空字段,就将SELECT * 替换成 DELETE c;
如果Customer中的PersonGuid是个可空字段,则将其置为空,将SELECT * 替换成 UPDATE c SET c.PersonGuid = null
-
删除原表
DROP TABLE Customer_REN