一劳永逸的数据库升级方案

数据库升级方案

一、面临的问题

在项目中数据库升级是经常遇到的事情,这个工作比较繁琐,特别是在线数据库升级需要十分小心,我们先来看一下通常面临的问题:

1、    表修改,包括增加了字段、修改了字段类型或者长度,更换了主键等。对于表的升级不能删除重建,需要单独修改,或者写脚本来升级。

2、    视图的修改,视图的修改比较简单,无非是增加了字段,取消了字段,不影响基础数据。视图的升级可以删除重建。

3、    存储过程的修改,存储过程的修改和视图一样,可以删除重建,二者都可以通过脚本来完成。

4、    函数的修改,如果项目中用到了函数,函数的升级和存储过程一样,不再赘述。

5、    上述情况基本能涵盖了大部分的数据库升级的情景,这些工作可以在数据库管理工具中完成,也可编写脚本来完成。我想说的问题并不是这个,而是有时候我们不知道那个表,那个字段修改了,除非你每改一个地方都做好记录,尽管如此,在升级的时候也难免落下。

我们公司有一套开发平台、由此平台开发了一套进销存,一套oa系统,而进销存又延伸出两套行业版进销存:鞋服通和医药通,以上产品有兴趣的可以去官网www.hfbpm.com试用,产品线如下图:

数据库和基础功能都是继承的,即进销存使用开发平台中的表,医药通和鞋服通使用通用进销存中的表,oa使用开发平台中的表,那么它们之间的数据库升级就非常频繁,刚开靠手工记录改动的地方,针对性的升级,后来发现工作量非常大,而且经常出错。

有没有一个一劳永逸的办法,比较差异进行数据库升级?只要思想不滑坡办法总比困难多!

办法肯定是有的。

二、解决方案

要解决数据库升级,主要是解决针对表、视图、存储过程函数的升级,后面三个相对来说比较简单,直接删除重建即可,难点是如何获取三者的创建脚本?只要获取到完整的脚本,当做sql语句执行即可,mssqlServer也给出了方法(下面会具体介绍)。表的升级相对来说要麻烦一些,因为表不能删除重建,必须对列、主键、约束等逐项进行比较升级,对于新建的表没有提供获取创建表脚本的方法,需要自己来处理。

下面详细介绍升级过程。

1、  表创建

MsSqlServer没有提供获取创建表脚本的方法,需要自己根据列属性生成创建脚本,为此我们编写了一个存储过程Sys_TableScript_MSSQL来做这件事情,存储过程的代码如下图:

由于篇幅限制,详细代码就不贴出来了,这个方法也是从博客园里收到的,稍微改动了一下,执行后输出的结果如下:

获取的是一个完整的创建表的脚本,该脚本当做普通的sql语句执行即可。

2、表升级

当表已经存在时,针对列进行升级,如果列不存在直接创建,如果列存在,那么是否升级判断依据是长度、类型、小数点位数、允许为空、默认值是否发生改变,上述只要有其一发生变化就要升级。

创建列的sql脚本,如下:

ALTER TABLE 表名 ADD 列名  类型  not null default ‘默认值‘

例如

ALTER TABLE dx_ZhiBan ADD  leaderName  varchar(50)  not null default ‘未填‘

如果列已经存在需要使用修改列的sql脚本,如下:

ALTER TABLE 表名 alter column 列名 类型 not null

例如

alter table dx_ZhiBan alter column Leader nvarchar(50) not null

修改列时如果修改默认值,修改列的脚本不支持直接修改默认值,因为列一旦创建了默认值,那么就创建了一个约束,需要先删除这个约束,再重新创建默认值。删除默认值约束需要先找到默认值约束的名字,再执行删除约束脚本。查找默认值约束的sql脚本如下:

select c.name from sysconstraints a

inner join syscolumns b on a.colid=b.colid

inner join sysobjects c on a.constid=c.id

where a.id=object_id(‘表名‘) and b.name=‘列名‘

找到约束的名字如下图:

删除默认值约束的sql脚本如下图:

alter table 表名 drop constraint 默认值约束名

例如:

alter table dx_ZhiBan drop constraint DF__dx_ZhiBan__Leade__3FE65219

删除默认值后,再执行创建默认值的sql脚本,如下:

alter table 表名 add default ‘默认值‘ for 列名 with values

例如:

alter table dx_ZhiBan add default ‘未填‘ for Leader with values

表的升级除了列还包括主键,主键的升级和默认值类似(因为他们都属于约束),需要先删除原来,再创建新的。查找主键约束的sql脚本如下:

  Select name from sysobjects where Parent_Obj=OBJECT_ID(‘表名‘) and xtype=‘PK‘

例如:

 Select name from sysobjects where Parent_Obj=OBJECT_ID(‘dx_ZhiBan‘) and xtype=‘PK‘

查找结果如下:

删除主键约束的sql脚本如下:

Alter table dx_ZhiBan Drop PK_dx_ZhiBan

创建主键的sql脚本如下:

ALTER TABLE dx_ZhiBan ADD PRIMARY KEY (ID, leader )

注意,联合主键用逗号分隔,另外,需要说明的是在升级之前要判断主键是否需要升级,如果主键没有变化就不需要升级。

3、视图升级

视图升级过程较简单,删除掉重新创建即可。删除视图的sql脚本如下:

drop view 视图名

获取视图创建脚本的sql脚本,如下:

EXEC sp_helptext @objname=‘视图名称‘

执行后结果如下图:

获取到该脚本后,当做普通的sql语句执行即可。

4、存储过程、函数升级

二者的升级和视图类似,不再赘述,不同的是删除存储过程的sql脚本是:

drop procedure 存储过程名

删除函数的sql脚本是:

drop function 函数名

5、数据库升级工具

数据库的升级是都能通过sql脚本来完成的,把这些脚本管理起来需要借助程序来完成,我们使用net的WinForm来编写程序。如下图:

使用这个工具可以选择那些对象需要升级(没有勾选的不升级),升级的时候能看到进度和升级结果。

本方案并不是十全十美的,有些问题还没解决,例如列名称修改、如何删除多余的列等。其他不当之处欢迎大家留言指正。

原文地址:https://www.cnblogs.com/legweifang/p/11332769.html

时间: 2024-10-09 06:39:16

一劳永逸的数据库升级方案的相关文章

打造android ORM框架opendroid(七)——数据库升级方案

在上一篇博客<打造android ORM框架opendroid(六)--级联查询>我们讲了OpenDroid最后一块功能查询的实现原理.今天我们将进行OpenDroid一个重头戏,也是本系列博客的最后一篇--数据库升级方案. 说道数据库升级,我可是很头疼的, 为什么呢? 因为以前的项目中,根本没有考虑数据库升级方案的问题,就直接drop table了,这样导致的结果就是"以前的数据都消失了".额... 凭空消失确实不是很少的一件事,如果数据不重要还行,重要数据呢? 说消失就

Android数据库无缝升级方案

软件迭代过程中,业务不断更新,也要求软件持续更新.相应地,数据库更新升级也是不可避免的一个环节.Android作为客户端应用,数据库升级相对于服务端来说会麻烦一些.常见的升级方式有: 1.删除旧表和数据,创建新表.优点是简单方便,缺点是丢失了旧数据.适用于应用数据依赖度低的情况. 2.在代码中兼容处理各版本数据库,创建新表,迁移旧数据到新表.优点是保留了旧数据,缺点是需要处理兼容个版本数据库差异,比较麻烦.如果通过代码来记录维护版本差异,会导致代码臃肿且极易出错. 本文介绍一种简单无缝的数据库升

SEP迁移升级方案

方案一.灾难恢复后升级 实施前提条件:更换服务器系统/重装服务器系统,但保持主机名和IP地址不变. 实施步骤: 1.先备份原有SEPM服务器数据库 1.1到文件夹C:/program files/Symantec /Symantec endpoint protection manager/data/backup下检查是否有下面三个文件keystoreXXX.jsk,serverxxx.xml,及xxx.zip文件,xxx为当日日期.将此三分文件拷贝到其他位置备用. 2.在新的服务器上安装SEPM

Android 数据库升级完整解决方案

数据库升级的意义 我们在开发Android应用的时候,不可避免地要使用数据库.而数据库的结构在第一版的时候定下来,之后发布功能更新,或增加业务逻辑,原来的数据库结构可能就不适用了.而如果数据库的结构与之前版本的结构不同,新版本的应用读取旧数据库肯定会出问题.解决办法只有两种: 1.让用户卸载老版本再安装新的程序: 2.软件自行更新数据库结构. 第一种办法很明显不具备可操作性,而且用户一旦卸载软件,数据就丢失了,这是不能容忍的事情.因此,作为开发者必须妥善处理数据库的升级问题. 当然了,有的同学会

针对数据库升级版本信息采集脚本编写

[环境介绍] 系统环境:Linux + 11G+ 集群/单机 [背景描述] 需求:每个季度都会有数据库漏洞扫描修复的事情,了解该扫描方式是根据数据库版本来进行判断是否当前数据库版本是否修复相应漏洞.而已一般漏洞信息分DBMS/OJVM/GRID类型漏洞.如果是当前维护的数据库,自己取数据库版本信息比较容易,但是大多时候接到协助升级的时候收集信息比较麻烦.需要较快的采取数据库版本信息和系统信息来进行写方案或者判断当前数据库是否需要升级及风险判断. [监控优化过程及思路] 对于上面描述的问题: 1,

探索Oracle之数据库升级二 11.2.0.3升级到11.2.0.4完整步骤

探索Oracle之数据库升级二  11.2.0.3升级到11.2.0.4完整步骤 说明:         这篇文章主要是记录下单实例环境下Oracle 11.2.0.1升级到11.2.0.3的过程,当然RAC的升级是会有所不同.但是他们每个版本之间升级步骤都是差不多的,先升级Database Software,再升级Oracle Instance. Oracle 11.2.0.4的Patchset No:19852360下载需要有Oracle Support才可以.  Patchset包含有7个

数据库升级问题—ORA-39700: database must be opened with UPGRADE option

1. 错误描述 一个数据较长时间未使用了,最近启动时出现如下错误: SQL> startup Oracle instance started. Total System Global Area 4932501504 bytes Fixed Size                  2103096 bytes Variable Size            889194696 bytes Database Buffers        4026531840 bytes Redo Buffers

数据库升级ora-04063 DBMS_REGISTRY has error

在做Oracle数据库从11.2.0.1.0升级到11.2.0.2.8时,软件升级没有问题,实例升级没有问题,升级psu的时候. 运行@?/rdbms/admin/catbundle psu apply时,只显示一部分信息,即终止apply. 在dba_registry_history中未显示11.2.0.2.8的psu信息: select * from dba_registry_history; ACTION_TIME                    ACTION          NA

Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())

数据库版本升级对软件的管理操作. 我们手机经常会收到xxx软件升级什么的提醒,你的软件版本更新,同时你的数据库对应的版本也要相应的更新. 数据库版本更新需要主要的问题: 软件的1.0版本升级到1.1版本时,老的数据不能丢. 那么在1.1版本的程序中就要有地方能够检测出来新的软件版本与老的数据库不兼容,并且能够有办法把1.0软件的数据库升级到1.1软件能够使用的数据库. 换句话说,要在1.0软件的数据库的那个表中增加那个字段,并赋予这个字段默认值. 当然有的时候我们对更新后的 版本并没有什么好感,