根据某几个条件对比两个表中的不同数据,注:两个表里面的字段数据不同,只部分字段相同,字段顺序不同

解决方案 »

  1.   

    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) --要比较的数据库名2
    as
    create 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 a
    left join '+@dbname1+'..systypes b on a.xtype=b.xusertype
    inner 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.id
    left 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 a
    left join '+@dbname2+'..systypes b on a.xtype=b.xusertype
    inner 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.id
    left 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.表名2
    when b.表名2 is null and a.序号=1 then '库2缺少表:'+a.表名1
    when 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 a
    full 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
      

  2.   

    字段数据不同,只部分字段相同,字段顺序不同是不是只比较字段相同的?比较两个查询的结果,返回非重复值。EXCEPT 从左查询中返回右查询没有找到的所有非重复值。INTERSECT 返回 INTERSECT 操作数左右两边的两个查询都返回的所有非重复值。
      

  3.   


    表结构比较:
    -------------------------------------------------------------------------------------------
    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)--要比较的数据库名2
    as
    create 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 a
    left join '+@dbname1+'..systypes b on a.xtype=b.xusertype
    inner 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.id
    left 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 a
    left join '+@dbname2+'..systypes b on a.xtype=b.xusertype
    inner 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.id
    left 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.表名2
    when b.表名2 is null and a.序号=1 then '库2缺少表:'+a.表名1
    when 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 a
    full 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
      

  4.   

    如果是数据不同,这得一个表一个表的比较.大概就是not in , not exists等.
      

  5.   

    如果你是比较表中数据的差异, 并且满足"两个表有主键(或者唯一约束)"那么, 你可以使用 sql 2005 提供的 tablediff 这个小工具(可以用于 2000, 但在安装了 sql 2005 才会有)比较的方法是:
    1. 根据你的条件, 对于要比较的两个表建立视图, 要求将要比较的列通过别名指定了相同的名称(即保证两个视图输出的结果集是一样的)
    2. 使用 tablediff 指定这两个视图进行比较. 参考及用法可以参考我的 blog: http://blog.csdn.net/zjcxc/archive/2006/12/27/1464953.aspx有必要的话, 可以指定 /f 指定修正差异的 sql 文件, 这样 tablediff 会生成主表数据同步到目标表的脚本文件
      

  6.   

    create table test1(
    pkid int identity(1,1) primary key,
    che varchar(50),
    ren varchar(50),
    money float,
    qt varchar(50)
    )
    insert into test1 values('鄂A08','赵',100,'P008')
    insert into test1 values('鄂A07','赵',200,'P000')
    insert into test1 values('鄂A06','钱',300,'P003')
    insert into test1 values('鄂A05','孙',400,'P002')
    insert into test1 values('鄂A04','李',500,'P001')
    insert into test1 values('鄂A03','周',600,'P007')
    create table test2(
    pkid int identity(1,1) primary key,
    che2 varchar(50),
    ren2 varchar(50),
    money2 float,
    qt2 varchar(50),
    qt3 varchar(50)
    )
    insert into test2 values('鄂A08','赵',100,'P008','备注')
    insert into test2 values('鄂A07','赵',200,'P000','备注')
    insert into test2 values('鄂A06','钱',300,'P003','备注')
    insert into test2 values('鄂A05','孙',600,'P002','备注')
    insert into test2 values('鄂A04','李',500,'P001','备注')
    insert into test2 values('鄂A03','周',400,'P007','备注')
    --------------------------
    就是根据两表中ceh,ren相同,money不同来对比出两表异同的数据
      

  7.   

    用sql语句实现,因为我做的那个程序有可能要转成ac数据库,现在不能用存储等,
    大家帮下忙~
      

  8.   

    写 sql 还不能用存储过程? 那动态条件如何做? 估计没法直接写 sql