SQLSERVER中统计所有表的记录数

   今天群里的一个朋友问了个问题: 如何把数据库里所有表的记录数都统计出来?
   由于以前我曾经试着写过一个存储过程,作用就是删除所有表的内容,思路是这样的:
   首先通过sysobjects表构造一个sql语句字符串'DELETE 表名',其中表名就是sysobjects中的name列,把这些DELETE语句字符串连接起来的方法一是通过游标,二则是直接利用如下语句:
   select @sql = @sql + 'DELETE ' + name from sysobjects where xtype='U';
   这是一个很有用的技巧,在合适的地方用会很大程度的优化语句运行速度.
   然后就是通过exec(@sql)执行该字符串.
   而把数据库所有表的记录数统计出来和这个思路几乎完全一样,不同的就是把'DELETE 表名' 改为'SELECT 表名,COUNT(1) FROM 表名',主要这点不同而已,如果构造完字符串并执行完毕,可以把结果输出到一个临时表,那么再统计所有记录数就轻而易举了.
    下面就是我写的一个语句:

 

None.gif declare   @sql   varchar ( 8000 ), @count   int , @step   int
None.gif
None.gif
set  nocount  on
None.gif
None.gif
-- @step越大运行速度越快,但如果太大会造成生成的sql字符串超出限制导致语句不完整出错
None.gif

None.gif
-- 建议为50
None.gif

None.gif
set   @step   =   50
None.gif
None.gif
if   object_id (N ' tempdb.db.#temp ' is   not   null
None.gif
None.gif
drop   table  # temp
None.gif
None.gif
create   table  # temp  (name sysname, count  numeric( 18 ))
None.gif
None.gif
if   object_id (N ' tempdb.db.#temp1 ' is   not   null
None.gif
None.gif
drop   table  #temp1
None.gif
None.gif
create   table  #temp1 (id  int   identity ( 1 , 1 ),name sysname)
None.gif
None.gif
insert   into  #temp1(name)
None.gif
None.gif
select  name  from  sysobjects  where  xtype  =   ' u ' ;
None.gif
None.gif
set   @count   =   @@rowcount   while   @count > 0
None.gif
None.gif
begin
None.gif
None.gif
set   @sql   =   ''
None.gif
None.gif
select   @sql   =   @sql   +   '  select  '''   +  name  +   ''' ,count(1) from  '   +  name  +   '  union '
None.gif
None.gif
from  #temp1  where  id  >   @count   -   @step   and  id  <=   @count
None.gif
None.gif
set   @sql   =   left ( @sql , len ( @sql -   len ( ' union ' ))
None.gif
None.gif
insert   into  # temp   exec  ( @sql )
None.gif
None.gif
set   @count   =   @count   -   @step
None.gif
None.gif
end
None.gif
None.gif
select   count ( count ) 总表数, sum ( count ) 总记录数  from  # temp
None.gif
None.gif
select   *   from  # temp   order   by   count ,name
None.gif
None.gif
set  nocount  off
None.gif

    经过测试,该方法可以通过,不过有时候@step的值需要手动设置一下,@step=50应该就可以满足大部分数据库的需要了.如果表名都比较短的话,可以设置@step=80或者100.

    后来我又去上网搜索其他统计数据库所有表记录数的语句,发现了下面的方法:

None.gif create   table  #(id  int   identity  ,tblname  varchar ( 50 ),num  int )
None.gif
None.gif
declare   @name   varchar ( 30 )
None.gif
None.gif
declare  roy  cursor   for   select  name  from  sysobjects  where  xtype = ' U '
None.gif
None.gif
open  roy
None.gif
None.gif
fetch   next   from  roy  into   @name
None.gif
None.gif
while   @@fetch_status = 0
None.gif
None.gif
begin
None.gif
None.gif
declare   @i   int
None.gif
None.gif
declare   @sql   nvarchar ( 1000 )
None.gif
None.gif
set   @sql = ' select @n=count(1) from  ' + @name
None.gif
None.gif
exec  sp_executesql  @sql ,N ' @n int output ' , @i  output
None.gif
None.gif
insert   into  #  select   @name , @I
None.gif
None.gif
fetch   next   from  roy  into   @name
None.gif
None.gif
end
None.gif
None.gif
close  roy
None.gif
None.gif
deallocate  roy
None.gif
None.gif
select   *   from  #
None.gif

    该方法用到了游标,如果数据库表很多的话速度可能会比较慢,但是该表不受表名长短影响,对所有数据库都适用.

    第三种方法,利用系统的对象表和索引表:

None.gif set  nocount  on
None.gif
if   object_id (N ' tempdb.db.#temp ' is   not   null
None.gif  
drop   table  # temp
None.gif
create   table  # temp  (name sysname, count  numeric( 18 ))
None.gif
None.gif
insert   into  # temp
None.gif
select  o.name,i.rows
None.gif
from  sysobjects o,sysindexes i  
None.gif
where  o.id = i.id  and  o.Xtype = ' U '   and  i.indid < 2
None.gif
None.gif
select   count ( count ) 总表数, sum ( count ) 总记录数  from  # temp
None.gif
select   *   from  # temp
None.gif
set  nocount  off
None.gif

    该方法执行速度绝对最快,但是结果好象并不是太准确,稍微有一些偏差.所以如果对数据量比较大而且对统计结果要求比较低的,该方法绝对是第一选择.如果要求统计绝对准确的记录数而且表的数量比较多的话,个人感觉第一个方法应该是个不错的选择.

    第三个方法主要是利用了系统索引表sysindexes中索引ID indid<1的行中的rows列存有该表的行数这一特点.

    最后一种方法是利用隐藏未公开的系统存储过程 sp_MSforeachtable
None.gif CREATE   TABLE  # temp  (TableName  VARCHAR  ( 255 ), RowCnt  INT )
None.gif
EXEC  sp_MSforeachtable  ' INSERT INTO #temp SELECT  '' ? '' , COUNT(*) FROM ? '
None.gif
SELECT  TableName, RowCnt  FROM  # temp   ORDER   BY  TableName
None.gif
DROP   TABLE  # temp
       从mssql6.5开始,微软提供了两个不公开,非常有用的系统存储过程 sp_MSforeachtablesp_MSforeachdb,用于遍历某个数据库的每个表和遍历DBMS管理下的每个数据库。

转载于:https://www.cnblogs.com/neekerss/archive/2011/03/24/1994005.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值