2015-04-23 57 views
0

我想获取数据库列表中所有表的大小。我遇到的问题是,每个数据库中的表都有相同的名称。如何添加第一列与数据库名#tmpTableSizes:如何动态添加列到临时表?

CREATE TABLE #tmpTableSizes 
(
    tableName varchar(100), 
    numberofRows varchar(100), 
    reservedSize varchar(50), 
    dataSize varchar(50), 
    indexSize varchar(50), 
    unusedSize varchar(50) 
) 

insert #tmpTableSizes 
EXEC AAABD.dbo.sp_MSforeachtable @command1="EXEC sp_spaceused '?'" 
insert #tmpTableSizes 
EXEC BBBDB.dbo.sp_MSforeachtable @command1="EXEC sp_spaceused '?'" 
insert #tmpTableSizes 
EXEC CCCDB.dbo.sp_MSforeachtable @command1="EXEC sp_spaceused '?'" 

回答

1

简单的解决办法:用多了一个“缓冲”表,先插入到缓存表,然后从它变成“主”临时表的规范DBNAME

CREATE TABLE #tmpTableSizes 
(
    dbName varchar(100), 
    tableName varchar(100), 
    numberofRows varchar(100), 
    reservedSize varchar(50), 
    dataSize varchar(50), 
    indexSize varchar(50), 
    unusedSize varchar(50) 
) 


CREATE TABLE #tmpTableSizesDB 
(
    tableName varchar(100), 
    numberofRows varchar(100), 
    reservedSize varchar(50), 
    dataSize varchar(50), 
    indexSize varchar(50), 
    unusedSize varchar(50) 
) 

insert #tmpTableSizesDB 
EXEC AAABD.dbo.sp_MSforeachtable @command1="EXEC sp_spaceused '?'" 

insert into #tempTableSizes 
select 'AAABD', * from #tempTableSizesDB 

truncate table #tempTableSizesDB 

insert #tmpTableSizesDB 
EXEC BBBDB.dbo.sp_MSforeachtable @command1="EXEC sp_spaceused '?'" 

insert into #tempTableSizes 
select 'BBBDB', * from #tempTableSizesDB 

truncate table #tempTableSizesDB 

insert #tmpTableSizesDB 
EXEC CCCDB.dbo.sp_MSforeachtable @command1="EXEC sp_spaceused '?'" 

insert into #tempTableSizes 
select 'CCCDB', * from #tempTableSizesDB 

或者你也可以使用动态SQL中环做:

create table dbo.#DBases (Name nvarchar(100)) 
insert into dbo.#DBases 
select 'AAABD' 
union all 
select 'BBBDB' 
union all 
select 'CCCDB' 


create table dbo.#tmpTableSizes 
(
    dbName varchar(100), 
    tableName varchar(100), 
    numberofRows varchar(100), 
    reservedSize varchar(50), 
    dataSize varchar(50), 
    indexSize varchar(50), 
    unusedSize varchar(50) 
) 


create table dbo.#tmpTableSizesDB 
(
    tableName varchar(100), 
    numberofRows varchar(100), 
    reservedSize varchar(50), 
    dataSize varchar(50), 
    indexSize varchar(50), 
    unusedSize varchar(50) 
) 

declare @stmt nvarchar(max), @DBName nvarchar(100) 

declare cur cursor for select Name from dbo.#DBases 
open cur 

fetch next from cur into @DBName 

while (@@fetch_status = 0) 
begin 
    select @stmt = 'truncate table dbo.#tmpTableSizesDB 

        insert into dbo.#tmpTableSizesDB 
        EXEC ' + @DBName + '.dbo.sp_MSforeachtable @command1="EXEC sp_spaceused ''?''" 

        insert into dbo.#tmpTableSizes 
        select ''' + @DBName + ''', * from dbo.#tmpTableSizesDB' 

    exec sp_executesql @stmt = @stmt 

    fetch next from cur into @DBName 
end 

close cur 
deallocate cur 

drop table dbo.#tmpTableSizesDB 
drop table dbo.#DBases 

select * from dbo.#tmpTableSizes 
+0

这是有效的,但看起来不是很优雅,因为我有几个数据库,有可能在循环中做到这一点? – Whistler

+0

@Whistler好吧,你可以在循环中使用一些动态sql来完成。 –

+0

我试过了,但是,我怎样才能在EXEC AAABD.dbo.sp_MSforeachtable @ command1 =“EXEC sp_spaceused'?'”中替换动态db名称(AAABD)? – Whistler

1

简单,

做插入时

CREATE TABLE #tmpTableSizes 
( dbname varchar(100), 
    tableName varchar(100), 
    numberofRows varchar(100), 
    reservedSize varchar(50), 
    dataSize varchar(50), 
    indexSize varchar(50), 
    unusedSize varchar(50) 
); 

你必须列出列和更新所有新插入的行DBNAME(这是唯一和dbname为空)

insert #tmpTableSizes 
    (tableName, numberofRows, reservedSize, dataSize, indexSize, unusedSize) 
EXEC AAABD.dbo.sp_MSforeachtable @command1="EXEC sp_spaceused '?'"; 

update #tmpTableSizes set dbname='AAABD' where dbname is null; 

添加列DBNAME

因为你增加了主意,做一个循环:

exec sp_msforeachdb 
'insert #tmpTableSizes 
    (tableName, numberofRows, reservedSize, dataSize, indexSize, unusedSize) 
EXEC ?.dbo.sp_MSforeachtable @command1=''EXEC ?.dbo.sp_spaceused ''!'' @replacechar=''!'' 
', '?', 
'update #tmpTableSizes set dbname=''?'' where dbname is null'; 

不太清楚,如果我增加了足够',你必须检查