关于多个数据库记录数以及表字段对比

头像
qinrui189
2019-01-21阅读 1477

通过简单的SQL语句很难实现,也许得写上万条Count(1),也许还得加上sysobject.

经研究,只有存储过程实现最方便,下面用例:SQL SERVER 2014实现

需求:两张表同时有200条记录,分别在不同的两个数据库。

方法一:需要创建第三数据库,将200条记录存放到第三数据库并创建一张临时表并且添加序号,方便后续使用

1.创建变量,对变量赋值

2.创建数据库游标,循环游标

3.创建表游标,循环表游标,动态执行游标EXEC

4.使用系统存储过程input ouput

5.输出临时表得到结果

上图

use master
go

if exists(select 1 from [tempdb].sys.sysobjects where [id] = OBJECT_ID('tempdb..#temp_1017'))
begin
drop table #temp_1017
end
create table #temp_1017 (temp_dbname nvarchar(50) ,temp_tblname nvarchar(100),row_num int)

--表名变量
declare @tablename nvarchar(100)
--库名变量
declare @dbname nvarchar(50)
--记录数变量
declare @i int

--查找表记录数的语句
declare @sql nvarchar(4000)

--查找库名的游标
declare dbnameSelect_cursor cursor for
select [name] from master.sys.sysdatabases where [name] like 'L0%' or [name] like 'BK_L0%' or [name] = 'DMSTest'

open dbnameSelect_cursor
--dbnameSelect_cursor 游标移动到第一行
fetch next from dbnameSelect_cursor into @dbname
while @@fetch_status=0
begin
--动态定义查找库中所有表记录数的游标 roy
exec (N'declare roy cursor for select name from '+ @dbname + N'.sys.sysobjects where upper(xtype)=''U''')


--查找表名的游标
--declare roy cursor for select name from L0Y01.sys.sysobjects where upper(xtype)='U'

--打开 游标
open roy
--游标移动到第一行
fetch next from roy into @tablename

while @@fetch_status=0
begin
set @sql= N'select @i=count(1) from '+ @dbname + N'.dbo.['+ @tablename + N']'
--print @sql
exec sp_executesql @sql,N'@i int output',@i output

insert into #temp_1017 select @dbname, @tablename ,@i

fetch next from roy into @tablename

end
close roy
deallocate roy

fetch next from dbnameSelect_cursor into @dbname
end

close dbnameSelect_cursor
deallocate dbnameSelect_cursor

--select * from #temp_1017

--declare @i int
--exec sp_executesql N'select @n=count(1) from L0Y01.dbo.Address',N'@n int output',@i output
--print @i

--drop table #temp_1017

--select * from #temp_1017 t where t.temp_dbname = N'L0Y01'
--and t.temp_tblname = N'L0Y01 Zhongsheng$G_L Entry'

select DMSBK_TBRows.temp_dbname,DMSBK_TBRows.temp_tblname,DMSBK_TBRows.row_num , DMSDLR_TBRows.temp_dbname as dlrdbname , DMSDLR_TBRows.row_num as dlrRow_num from
(select * from #temp_1017 t where t.temp_dbname = N'DMSTest') DMSBK_TBRows
left join
(select * from #temp_1017 t where t.temp_dbname <> N'DMSTest') DMSDLR_TBRows
on DMSBK_TBRows.temp_tblname = DMSDLR_TBRows.temp_tblname
--and substring(DMSBK_TBRows.temp_dbname,0,5) = DMSDLR_TBRows.temp_dbname
where DMSBK_TBRows.row_num <> DMSDLR_TBRows.row_num


方法二:与方法一类似,去掉了多余的游标,直接来循环序号,每找到一条循环一次

Declare @cnt int,@dlrold varchar(10),@dlrnew varchar(10),@tbold varchar(100),@tbnew varchar(100),@sql varchar(4000),@tableid varchar(10)
set @cnt=0
set @dlrold='Online_Shopping_Mall'
create table #tb(Status1 varchar(50),Status2 varchar(50),Status3 int)
while @cnt<3
begin
set @cnt=@cnt+1
set @tbold=(select rtrim(name) from DMSAuto.dbo.DMS_Cursor1 where No_=@cnt)
print @tbold

set @tableid=convert(varchar,@cnt)
--@tableid代表序号
--oldtable代表DMS_Cursor1表
--@dlrold代表Online_Shopping_Mall数据库
set @sql='insert into #tb(Status1,Status2,Status3)
select tableid,tbold,CNt from
(select '''+@tableid+''' as tableid,'''+@tbold+''' as tbold,a.CNT from
(select count(1) as CNT from Online_Shopping_Mall..[' + @tbold + '])a) a'
print @sql
exec (@sql)
end

select Status2 as 表名,Status3 as 记录数 from #tb

drop table #tb


[坏笑]

码农笔录: 大佬,看不懂 回复