首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

新旧数据库对比,自动生成更新语句

2012-02-06 
求助:新旧数据库对比,自动生成更新语句。情况是这样的 有旧数据库A,新数据库B可不可以通过比较A B,发现A,B

求助:新旧数据库对比,自动生成更新语句。
情况是这样的 
有旧数据库A,新数据库B

可不可以通过比较A B,发现A,B不同地方。然后自动生成 从数据库A升级到B的更新语句。
不能把B里面的数据删除掉重新建表。
不需要处理具体数据,只需要表结构,存储过程,函数。


[解决办法]
说得不太清楚?A,B是主键不同还是一整条记录不同?

[解决办法]

SQL code
表结构比较:-------------------------------------------------------if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_comparestructure]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)drop procedure [dbo].[p_comparestructure]GO/*--比较两个数据库的表结构差异可以比较两个数据库的结构差异--邹建 2003.9(引用请保留此信息)--*//*--调用示例exec p_comparestructure '库1','库2'--*/create proc p_comparestructure@dbname1 varchar(250),--要比较的数据库名1@dbname2 varchar(250)--要比较的数据库名2ascreate table #tb1(表名1 varchar(250),字段名 varchar(250),序号 int,标识 bit,主键 bit,类型 varchar(250),占用字节数 int,长度 int,小数位数 int,允许空 bit,默认值 sql_variant,字段说明 sql_variant)create table #tb2(表名2 varchar(250),字段名 varchar(250),序号 int,标识 bit,主键 bit,类型 varchar(250),占用字节数 int,长度 int,小数位数 int,允许空 bit,默认值 sql_variant,字段说明 sql_variant)--得到数据库1的结构exec('insert into #tb1 SELECT 表名=d.name,字段名=a.name,序号=a.colid,标识=case when a.status=0x80 then 1 else 0 end,主键=case when exists(SELECT 1 FROM '+@dbname1+'..sysobjects where xtype=''PK'' and parent_obj=a.id and name in (SELECT name FROM '+@dbname1+'..sysindexes WHERE indid in(SELECT indid FROM '+@dbname1+'..sysindexkeys WHERE id = a.id AND colid=a.colid))) then 1 else 0 end,类型=b.name,占用字节数=a.length,长度=a.prec,小数位数=a.scale,允许空=a.isnullable,默认值=isnull(e.text,''''),字段说明=isnull(g.[value],'''')FROM '+@dbname1+'..syscolumns aleft join '+@dbname1+'..systypes b on a.xtype=b.xusertypeinner join '+@dbname1+'..sysobjects d on a.id=d.id  and d.xtype=''U'' and  d.name<>''dtproperties''left join '+@dbname1+'..syscomments e on a.cdefault=e.idleft join '+@dbname1+'..sysproperties g on a.id=g.id and a.colid=g.smallid  order by a.id,a.colorder')--得到数据库2的结构exec('insert into #tb2 SELECT 表名=d.name,字段名=a.name,序号=a.colid,标识=case when a.status=0x80 then 1 else 0 end,主键=case when exists(SELECT 1 FROM '+@dbname2+'..sysobjects where xtype=''PK'' and parent_obj=a.id and name in (SELECT name FROM '+@dbname2+'..sysindexes WHERE indid in(SELECT indid FROM '+@dbname2+'..sysindexkeys WHERE id = a.id AND colid=a.colid))) then 1 else 0 end,类型=b.name,占用字节数=a.length,长度=a.prec,小数位数=a.scale,允许空=a.isnullable,默认值=isnull(e.text,''''),字段说明=isnull(g.[value],'''')FROM '+@dbname2+'..syscolumns aleft join '+@dbname2+'..systypes b on a.xtype=b.xusertypeinner join '+@dbname2+'..sysobjects d on a.id=d.id  and d.xtype=''U'' and  d.name<>''dtproperties''left join '+@dbname2+'..syscomments e on a.cdefault=e.idleft join '+@dbname2+'..sysproperties g on a.id=g.id and a.colid=g.smallid  order by a.id,a.colorder')--and not exists(select 1 from #tb2 where 表名2=a.表名1)select 比较结果=case when a.表名1 is null and b.序号=1 then '库1缺少表:'+b.表名2when b.表名2 is null and a.序号=1 then '库2缺少表:'+a.表名1when a.字段名 is null and exists(select 1 from #tb1 where 表名1=b.表名2) then '库1 ['+b.表名2+'] 缺少字段:'+b.字段名when b.字段名 is null and exists(select 1 from #tb2 where 表名2=a.表名1) then '库2 ['+a.表名1+'] 缺少字段:'+a.字段名when a.标识<>b.标识 then '标识不同'when a.主键<>b.主键 then '主键设置不同'when a.类型<>b.类型 then '字段类型不同'when a.占用字节数<>b.占用字节数 then '占用字节数'when a.长度<>b.长度 then '长度不同'when a.小数位数<>b.小数位数 then '小数位数不同'when a.允许空<>b.允许空 then '是否允许空不同'when a.默认值<>b.默认值 then '默认值不同'when a.字段说明<>b.字段说明 then '字段说明不同'else '' end,*from #tb1 afull join #tb2 b on a.表名1=b.表名2 and a.字段名=b.字段名where a.表名1 is null or a.字段名 is null or b.表名2 is null or b.字段名 is null or a.标识<>b.标识 or a.主键<>b.主键 or a.类型<>b.类型or a.占用字节数<>b.占用字节数 or a.长度<>b.长度 or a.小数位数<>b.小数位数or a.允许空<>b.允许空 or a.默认值<>b.默认值 or a.字段说明<>b.字段说明order by isnull(a.表名1,b.表名2),isnull(a.序号,b.序号)--isnull(a.字段名,b.字段名)go 


[解决办法]

SQL code
/*--数据结构比较    比较两个数据库中的视图/存储过程的结构(结构比较,不是功能比较)--邹建 2004.07(引用请保留此信息)--*//*--调用示例    --调用    exec p_compdb 'pubs','northwind'--*/create proc p_compdb@db1 sysname,    --第一个库@db2 sysname    --第二个库asexec('select 类型=case isnull(a.xtype,b.xtype) when ''V'' then ''视图'' else ''存储过程'' end    ,匹配情况=case         when a.name is null then ''库 ['+@db1+'] 中无''        when b.name is null then ''库 ['+@db2+'] 中无''        else ''结构不同'' end    ,对象名称=isnull(a.name,b.name)from(    select a.name,a.xtype,b.colid,b.text    from ['+@db1+']..sysobjects a,['+@db1+']..syscomments b    where a.id=b.id and a.xtype in(''V'',''P'') and a.status>=0)a full join(    select a.name,a.xtype,b.colid,b.text    from ['+@db2+']..sysobjects a,['+@db2+']..syscomments b    where a.id=b.id and a.xtype in(''V'',''P'') and a.status>=0)b on a.name=b.name and a.xtype=b.xtype and a.colid=b.colidwhere a.name is null    or b.name is null    or isnull(a.text,'''')<>isnull(b.text,'''')group by a.name,b.name,a.xtype,b.xtypeorder by 类型,匹配情况,对象名称')go
[解决办法]
SQL code
建议楼主用一下这个工具 SQL DELTA。http://cqdxdown.ddvip.com:81/down/SQLDelta4.zip挺不错的。
[解决办法]
探讨
二楼的我也有。我需要的是要自动生成两个数据库的升级语句

[解决办法]
探讨
二楼的我也有。我需要的是要自动生成两个数据库的升级语句

[解决办法]
探讨
引用:
引用:
二楼的我也有。我需要的是要自动生成两个数据库的升级语句

如果有自动的就好了.公司可以少大批的人了.



目前还没有这方面的的吗?

[解决办法]
探讨
引用:

你认为这样的东西可能存在吗?

必须针对不同的数据库自己编写相应的程序.


其实是这样的,数据库A 可能是半个月前的,数据库B是新的。大部分是相同的 可能在这半个月内,数据库里面的表结构等做过修改。比方说 A中的一个表增加过一个字段,或者修改过类型。

我需要的就是 生成更新语句,使得A数据库中的表结构更新到与B中的表结构一样

[解决办法]
请问龟仙,这个可不可以用T-SQL写出来
探讨
引用:
引用:

你认为这样的东西可能存在吗?

必须针对不同的数据库自己编写相应的程序.


其实是这样的,数据库A 可能是半个月前的,数据库B是新的。大部分是相同的 可能在这半个月内,数据库里面的表结构等做过修改。比方说 A中的一个表增加过一个字段,或者修改过类型。

我需要的就是 生成更新语句,使得A数据库中的表结构更新到与B中的表结构一样

那就…

[解决办法]
汗。龟仙帮你回答这么多次,是谁都不知道?
[解决办法]
探讨
请问龟仙

哪个是 龟仙

[解决办法]
...
[解决办法]
探讨
引用:
请问龟仙

哪个是 龟仙
13楼那个

[解决办法]
学习!学习!

[解决办法]
受教
[解决办法]
我们公司自己开发的‘管理员系统平台’都带两个数据库结构比较功能,且能自动生成更新语法,只对sybase和oracle的表结构好用。对函数和存贮过程不行。
[解决办法]
不错了代码
------解决方案--------------------


xl说:sf
[解决办法]
源贴地址
http://topic.csdn.net/u/20080906/23/69338b12-ed1d-4ef2-b1d3-3cde013c68e2.html



二库对比,循环调用此存储过程即可。
即,更新主体已出你了,你自己做循环控制部分可以了,比较简单,没什么可说的。



SQL code
/* 原创:fcuandy 修改:bing110 功能:动态传入“表名,字段名,字段类型,默认值”四个字符串,根据新的字段名称和类型来创表表结构 不足:由于修改的表时候保留原来字段的数据,所以现在暂时还不能修改字段类型,创建的表中也不能创建索引,外键约束等功能 日期:2008-9-9 */ CREATE  FUNCTION dbo.Split --自定义的拆分函数,用来装传入的字符串分隔成表 ( @ItemList VARCHAR(4000), @delimiter VARCHAR(10) ) RETURNS @IDTable TABLE (IndexID INT IDENTITY(1,1),Item VARCHAR(50)) AS     BEGIN     WHILE CHARINDEX(@delimiter, @ItemList)>0         BEGIN             INSERT @IDTable SELECT LEFT(@ItemList,CHARINDEX(@delimiter,@ItemList)-1)             SET @ItemList=STUFF(@ItemList,1,CHARINDEX(@delimiter,@ItemList),'')         END         INSERT @IDTable SELECT @ItemList     RETURN     END CREATE PROC P_Alter_Table @tb VARCHAR(100),  --表名 @fieldsLists VARCHAR(1000),  --字段列表 @fieldsTypeLists VARCHAR(1000),  --字段类型列表,需要与字段列表一一对应 @DefaultValue VARCHAR(1000)    --新增字段默认值,与字段一一对应 AS BEGIN     DECLARE @sql VARCHAR(8000)     DECLARE @sql1 VARCHAR(8000),@sql2 VARCHAR(8000),@Sql0 VARCHAR(8000)         IF object_id(@tb,'u') IS NULL --若表不存在         BEGIN             SELECT @sql=ISNULL(@sql + ',','') + '[' + a.Item + '] ' + b.Item +' Default '+CHAR(39)+ c.Item +CHAR(39)                 FROM dbo.Split(@fieldsLists,',') a             INNER JOIN                 dbo.Split(@fieldsTypeLists,',') b                 ON a.IndexID=b.IndexID             INNER JOIN dbo.Split(@DefaultValue,',') C                 ON a.IndexId=C.IndexId             EXEC('CREATE TABLE [' + @tb + '](' + @sql + ')')         END     ELSE  --若表存在         BEGIN             SELECT @sql1='',@sql2='',@sql0=''             SELECT  @sql1=@sql1 + CASE WHEN Field IS NULL THEN '['+name+'],' ELSE '' END,--记录待删除列列表                     @Sql0=@Sql0 + CASE WHEN Field IS NULL AND CDEFAULT <> 0 THEN (SELECT [NAME] FROM SYSOBJECTS WHERE ID=CDEFAULT) + ',' ELSE '' END, --记录待删除的默认值                     @sql2=@sql2 + CASE WHEN Name IS NULL THEN '['+Field+'] ' + FType + ' Default '+CHAR(39)+ DValue + CHAR(39)+',' ELSE '' END --记录待新增列列表                 FROM                 (SELECT [NAME],CDEFAULT FROM syscolumns WHERE id=object_id(@tb,'u')) a             FULL OUTER JOIN                 (                     SELECT b.Item Field,a.Item FType,c.Item DValue FROM                         dbo.Split(@fieldsLists,',') b                     INNER JOIN dbo.Split(@fieldsTypeLists,',') a                         ON a.IndexID=b.IndexID                     INNER JOIN dbo.Split(@DefaultValue,',') c                         ON a.IndexId=c.IndexId                 ) b                     ON name=Field             SELECT @sql1=STUFF(@sql1,LEN(@sql1),1,''),@sql2=STUFF(@sql2,LEN(@sql2),1,''),@sql0=STUFF(@sql0,LEN(@sql0),1,'')             IF LEN(@sql2)>0               EXEC('ALTER TABLE [' + @tb + '] ADD ' + @sql2)  --先加原表中不存在的列             IF LEN(@Sql0)>0                            EXEC('ALTER TABLE ['+ @TB+ '] DROP CONSTRAINT '+ @Sql0) --删除表中不需要字段的默认值             IF LEN(@sql1)>0               EXEC('ALTER TABLE [' + @tb + '] DROP COLUMN ' + @sql1)  --再删除新传入结构中不需要的列         END END Eg: EXEC P_ALTER_TABLE 'A','A1,A2','INT,VARCHAR(10)','0,T' SELECT * FROM A
[解决办法]
如果还需要处理主健、索引、约束等,自己再连下系统表,处理一下。
[解决办法]
帮顶,即使是路过
[解决办法]
:)
[解决办法]
学习啊!都是高人啊
[解决办法]
学习


[解决办法]
学习
[解决办法]
我也有这样的需求,写一个脚本..
http://download.csdn.net/source/1157973

[解决办法]
study
[解决办法]
学习
[解决办法]
楼主的表达不是很清楚。查查merge语句,可能可以实现楼主的需求。
[解决办法]
有工具,下一个就可以了。

好像叫:SQLDelta
[解决办法]
mark
[解决办法]
VS2005,VS2008自带有数据库比较Schema的工具,可以看下,是不是你想要的啊!!
项目---创建项目---选择"数据库项目",可以选择2000/2005

VS2008可以支持SQL2008的,不过得装一个GDR工具包!
[解决办法]
mark up
[解决办法]
最完美解答:
如果是Oracle数据库,用PL/SQL Developer的 tools--Compare User Object 功能,可以对比两个数据库,对比的差异直接生成SQL。


[解决办法]
Using PowerDesigner, this tool provides function to compare difference with model to DB schema in database or model in model-repository, also it can generate alter scripts automatically.

any difficultities, please contact me at bestysq@126.com
[解决办法]
学习了
[解决办法]
没有看明白
[解决办法]
帮lz
顶一下!!
[解决办法]
mark
[解决办法]
阅读阅读,但都觉得lz最终的目的就是把B的结构复制到A而已,要不要想的那么复杂??? 小的菜鸟各位大侠不要笑话~
[解决办法]

探讨
SQL code/*--数据结构比较

比较两个数据库中的视图/存储过程的结构(结构比较,不是功能比较)

--邹建 2004.07(引用请保留此信息)--*/

/*--调用示例

--调用
exec p_compdb 'pubs','northwind'
--*/
create proc p_compdb
@db1 sysname, --第一个库
@db2 sysname --第二个库
as
exec('
select 类型=case isnull(a.xtype,b.xtype) when ''V'' then ''视图'' else ''存储过程'' end
,匹配情…

[解决办法]
学习了
[解决办法]
正在学习中,好多前辈啊,要努力了!
[解决办法]
UP
[解决办法]
UP

热点排行