2011-01-20 4 views

ответ

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') 
+0

Не будет ли включать базы данных по умолчанию, такие как master, msdb и т. Д.? – Thomas

+0

@ Томас: Да. Они могут быть легко исключены из предложения WHERE, если они не нужны. Я пересмотрю свой ответ. –

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 однако, очевидно, более многословным.

+0

Это только получить число таблиц в текущей схеме, а не весь экземпляр. – thefroatgt

+0

@thefroatgt - Вы не знали, что вы имели в виду во всех базах данных экземпляра. Однако я предоставил решение. – Thomas

+0

+1 Должен использовать 'quotename (@DbName)', хотя на всякий случай имя базы данных содержит символ ']'. –

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; 
Смежные вопросы