SQL Server实例上有多少个表

时间:2011-01-20 16:03:43

标签: sql-server

如何找出我的SQL Server实例上有多少个表?我可以使用select count(*) from sysobjects where type = 'U'为单个架构获取它 (来自how to count number of tables/views/index in my database

4 个答案:

答案 0 :(得分:4)

你正在使用“架构”这个词,但我认为你真的要求在所有“数据库”中计算表格。

declare @t table (
    DBName sysname,
    NumTables int
)

insert into @t
    exec sp_MSforeachdb N'select ''?'', count(*) 
                              from [?].dbo.sysobjects 
                              where type = ''U'''

select DBName, NumTables
    from @t 
    where DBName not in ('distribution','master','model','msdb','tempdb')
    order by DBName

select SUM(NumTables) as TotalTables
    from @t
    where DBName not in ('distribution','master','model','msdb','tempdb')

答案 1 :(得分:1)

不使用隐藏的,未记录的sp_MSforeachdb

的选项
declare @sql nvarchar(max)

select @sql = coalesce(@sql + ' + ', '') + REPLACE('
 (select count(*)
 from ::DB::.sys.objects
 where is_ms_shipped = 0
   and type_desc = ''USER_TABLE'')', '::DB::', QUOTENAME(name))
from master.sys.databases
where owner_sid != 0x01

select @sql = 'select ' + @sql

exec (@sql)  -- returns a single count of all [user] tables in the instance

>

关于效果的说明。 更大的事物计划是无关紧要的,但是如果事情有趣,有人必定会计时。下面是通过临时表(它在内部使用游标)的ms_foreachdb方法与string-concat方法的比较。

-- all the variables that we will use
declare @i int -- loop variable
declare @sql nvarchar(max) -- statement var used for 1st approach
declare @t table (DBName sysname, NumTables int) -- table used for 2nd approach

-- init plan cache and buffers
dbcc freeproccache dbcc dropcleanbuffers

print convert(varchar(30), getdate(), 121)

set @i = 0 while @i < 5 begin
 set @sql = null
 select @sql = coalesce(@sql, '') + REPLACE('
  select @c = @c + count(*)
  from ::DB::.sys.objects
  where is_ms_shipped = 0
    and type_desc = ''USER_TABLE''', '::DB::', QUOTENAME(name))
 from master.sys.databases
 where owner_sid != 0x01
 select @sql = 'set nocount on declare @c int set @c = 0 ' + @sql + ' select @c'
 exec (@sql)

 -- clear plan cache and buffers after each run
 dbcc freeproccache dbcc dropcleanbuffers set @i = @i + 1
end

print convert(varchar(30), getdate(), 121)

set @i = 0 while @i < 5 begin
 insert into @t
  exec sp_MSforeachdb N'select ''?'', count(*) 
          from [?].dbo.sysobjects 
          where type = ''U'''

 select SUM(NumTables) as TotalTables
  from @t
  where DBName not in ('distribution','master','model','msdb','tempdb')

 -- unfortunately this is required
 delete from @t

 -- clear plan cache and buffers after each run
 dbcc freeproccache dbcc dropcleanbuffers set @i = @i + 1
end

print convert(varchar(30), getdate(), 121)

每个只进行5次调用(循环迭代)的结果。 YMMV

start                 : 2011-01-21 14:21:45.180
end of string-concat  : 2011-01-21 14:21:57.497 (12.317)
end of sp_msforeachdb : 2011-01-21 14:22:13.937 (16.440)

必须注意的是,必须在第二种方法的每次迭代之间清空临时表,这样才能有助于总时间。它应该是微不足道的

答案 2 :(得分:1)

这是一个不使用未记录的函数并在SQL Server 2005,2008和2008R2中工作的答案。只需稍作修改即可使用此答案在数据库中运行任何语句。


DECLARE @sql varchar(200), @dbname sysname, @dbid smallint;

CREATE table #alltables
(dbname sysname,
 [number of tables] int);

SELECT top 1 @dbname = name, @dbid = database_id
FROM sys.databases
where database_id > 4;

WHILE (@dbname is not null)
begin

    -- the statement below could contain any valid select statement
    set @sql = 'use ' + @dbname + '; insert into #alltables select ''' + @dbname + ''', count(*) from sys.tables';

    EXEC (@sql)

    set @dbname = null;

    SELECT top 1 @dbname = name, @dbid = database_id
    FROM sys.databases
    where database_id > @dbid;

end;

select * FROM #alltables;
SELECT sum([number of tables]) "Total Number of Tables in all user databases" from #alltables;

drop table #alltables;

答案 3 :(得分:0)

Select Count(*)
From INFORMATION_SCHEMA.TABLES
Where TABLE_TYPE = 'BASE TABLE'

如果您正在寻找的是确定给定SQL Server实例上所有数据库中存在多少表的方法,那么您需要遍历每个数据库。一种方法是:

Declare @Databases Cursor
Declare @DbName as nvarchar(64)
Declare @SQL nvarchar(max)
Declare @BaseSQL nvarchar(max)
Declare @Count int
Declare @TotalCount int

Set @Databases = Cursor Fast_Forward For
    select [name]
    from master..sysdatabases
    where [name] Not In('master','model','msdb','tempdb')

Open @Databases
Fetch Next From @Databases Into @DbName

Set @BaseSQL = 'Select @Count = Count(*) 
                    From DatabaseName.INFORMATION_SCHEMA.TABLES
                    Where TABLE_TYPE = ''BASE TABLE'''

Set @TotalCount = 0
While @@Fetch_Status = 0
Begin
    Set @Count = 0
    Set @SQL = Replace(@BaseSQL, 'DatabaseName', QuoteName(@DbName))

    exec sp_executesql @SQL, N'@Count int OUTPUT', @Count OUTPUT

    Set @TotalCount  = @TotalCount + @Count

    Fetch Next From @Databases Into @DbName
End

Close @Databases
Deallocate @Databases

Select @TotalCount

此解决方案的优点是不使用任何未记录的功能,例如sp_MSforeachdb,但它显然更冗长。