--刚才突然想到要写两个小程序, 写好了, 顺便拿出来共享一下
--欢迎指正
/*
[sql]查看数据库中各表的存储空间
*/
--==========================================================
--修改这里
use gpms --进入相应的数据库
go
--==========================================================
declare @dbname varchar(40)
declare @dbsize int
declare @sql nvarchar(1000)
declare @tablename varchar(40)
--==========================================================
--修改这里
set @dbname='gpms' --设置想要查询的数据库名字
--==========================================================
--创建存放各数据表所占用空间的中间表
if object_id('table_info') is not null drop table table_info
create table table_info(
Name nvarchar(40),
Rows char(21),
reserved varchar(28),
Data varchar(28),
index_size varchar(28),
Unused varchar(28))
--查看每一个用户表
DECLARE cur_table CURSOR
   FOR SELECT name FROM sysobjects where xtype='U'
OPEN cur_table
FETCH NEXT FROM cur_table into @tablenameSET NOCOUNT ON
WHILE @@FETCH_STATUS = 0
BEGIN
      insert table_info exec sp_spaceused @tablename      
      FETCH NEXT FROM cur_table into @tablename  
END
SET NOCOUNT OFF
CLOSE cur_table
DEALLOCATE cur_table
--求出数据库的大小
SET @sql=N'select @size=size from  '+@dbname+'..sysfiles where groupid=1'
print @sql
EXEC sp_executesql @sql, N' @size int OUTPUT', @dbsize output
--@size的单位为8KB
set @dbsize=@dbsize*8
select 数据名=@dbname,
       数据库大小=convert(varchar(40), @dbsize)+' KB',
       用户表的数目=convert(varchar(10), count(1))+' 个',
       所有表的数据所占的空间=convert(varchar(100), sum(convert(int, replace(data, 'KB', ''))))+' KB'       
from table_info
--输出表的信息
select 表名=Name,表中记录数=Rows, 为该表分配的总量=reserved,
       表中数据所占的空间=data, 表中索引所占的空间=index_size
from table_info order by data desc , rows desc
--清除
drop table table_info

解决方案 »

  1.   

    /*
    强制还原数据库
    */
    use master
    go
    declare @filename varchar(100)
    --======================================
    --修改这里
    set @filename='H:\filebat\temp\dbtemp_7_4' 
    --======================================
    --查看当前进程
    create table table_sp_who(spid int, ecid int, status varchar(100), loginame varchar(100),
    hostname varchar(100), blk int, dbname varchar(100), cmd varchar(100))
    insert table_sp_who exec sp_who
    declare @dbname varchar(100)
    declare @spid int
    --数据库名字
    set @dbname='gpms'
    --kill正在使用该数据库的进程
    DECLARE spid_db CURSOR
       FOR SELECT spid FROM table_sp_who where dbname=@dbname
    OPEN spid_db
    FETCH NEXT FROM spid_db into @spidWHILE @@FETCH_STATUS = 0
    BEGIN
          print '杀死正在使用数据库'+@dbname+'的进程:'+convert(varchar(10), @spid)+'\n'
          exec('kill '+@spid)
          FETCH NEXT FROM spid_db INTO @spid   
    ENDCLOSE spid_db
    DEALLOCATE spid_db
    --清除数据
    drop table table_sp_who
    --删除原数据库
    drop database gpms
    --使用动态SQL语句来还原数据库
    declare @sql varchar(400)
    set @sql='restore database '+@dbname+' from disk='
    set @sql=@sql+''''+@filename+''''
    print @sql+'\n'
    exec(@sql)
      

  2.   


    顺便问一下, 哪位大哥,知道怎么样才可以将use master这个语句用动态SQL语句来实现?
    因为想写一段SQL代码,要用到这种功能.
    数据库名是用户给定的, 代码运行先事先不知道
    因为里面要运行类似exec sp_spaceused的语句
      

  3.   

    联机丛书里很清楚了
    ---------------------------------------
    数据库环境的更改只在 EXECUTE 语句结束前有效。例如,在这个例子的 EXEC 后,数据库环境是 master:USE master EXEC ("USE pubs") SELECT * FROM authors
    ---------------------------------------我有二个库,x,d
    x里有表x,d里有表stuse x
    exec ('use d ;select * from st')
    select * from x
    也只能这样了.还是那个原因,exec内的语句与当前代码编译时不在同一空间,所以环境不一样的.就跟
    declare @i int
    exec('set @i=0')
    报错一样.至于有没有别的方法不太清楚.