从SQLSERVER6.5开始,MS提供了一个非常有用的系统存储过程sp_MSforeachtable和sp_MSforeachDB;作为DBA会经常需要检查所有的数据库或用户表,比如:检查所有数据库的容量;看看指定数据库所有用户表的容量,所有表的记录数,我们一般处理这样的问题都是用游标分别处理处理,比如:在数据库检索效率非常慢时,我们想检查数据库所有的用户表,我们就必须这样写游标:

 1SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBDECLARE @TableName varchar(255)
 2SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBDECLARE @ExeSQL varchar(4000
 3SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBDECLARE Table_Cursor CURSOR FOR SELECT [name] FROM sysobjects WHERE xtype='U'
 4SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBOPEN Table_Cursor
 5SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBFETCH NEXT FROM  Table_Cursor INTO @TableName
 6SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBWHILE(@@FETCH_STATUS=0)
 7SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBBEGIN
 8SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB PRINT @TableName
 9SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB SELECT @ExeSQL='DBCC CHECKTABLE('''+@TableName+''')'
10SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB EXEC(@EXESQL)
11SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBFETCH NEXT FROM  Table_Cursor INTO @TableName
12SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBEND
13SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBCLOSE Table_Cursor
14SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBDEALLOCATE Table_Cursor
15SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBGO

如果我们用sp_MSforeachtable就可以非常方便的达到相同的目的:
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBEXEC sp_MSforeachtable @command1="print '?' DBCC CHECKTABLE ('?')"

大家可以看出这样就更加简洁(虽然在后台也是通过游标来处理的),下面我们就仔细分析一下sp_MSforeachtable这个存储过程:

    我们看看sp_MSforeachtable详细的CODE:

 1SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBUSE MASTER 
 2SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBGO
 3SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBSP_HELPTEXT sp_MSforeachtable
 4SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB--下面时sp_MSforeachtable的原始代码
 5SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBCREATE proc sp_MSforeachtable
 6SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @command1 nvarchar(2000), @replacechar nchar(1= N'?'@command2 nvarchar(2000= null,
 7SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB   @command3 nvarchar(2000= null@whereand nvarchar(2000= null,
 8SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @precommand nvarchar(2000= null@postcommand nvarchar(2000= null
 9SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBas
10@retval

这个系统存储过程有7个参数:

1SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @command1 nvarchar(2000),  --第一条运行的T-SQL指令
2SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @replacechar nchar(1= N'?',   --指定的占位符号 
3SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @command2 nvarchar(2000= null,--第二条运行的T-SQL指令
4SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @command3 nvarchar(2000= null--第三条运行的T-SQL指令
5SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @whereand nvarchar(2000= null--可选条件来选择表
6SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @precommand nvarchar(2000= null--在表前执行的指令
7SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB @postcommand nvarchar(2000= null --在表后执行的指令

 所以上面的语句也可以这样写:

SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBEXEC sp_MSforeachtable @command1="print '?'",@command2= "DBCC CHECKTABLE('?')"

了解参数以后,就让我们做几个实列吧:
1.获得每个表的记录数和容量:

SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBEXEC sp_MSforeachtable @command1="print '?'",
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB         
@command2="sp_spaceused '?'",
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB         
@command3= "SELECT count(*FROM ? "
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
2.更新PUBS数据库中已t开头的所有表的统计:
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBEXEC sp_MSforeachtable @whereand="and name like 't%'",
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB         
@replacechar='*',
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB         
@precommand="print 'Updating Statistics.....' print ''",
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB         
@command1="print '*' update statistics * ",
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB         
@postcommand= "print''print 'Complete Update Statistics!'"
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
sp_MSforeachDB除了@whereand外,和sp_MSforeachtable的参数是一样的,我们可以通过这个存储过程检测所有的数据库,比如: 1.获得所有的数据库的存储空间:
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB       EXEC sp_MSforeachdb  @command1="print '?'", @command2="sp_spaceused "
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
2.检查所有的数据库
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB       EXEC sp_MSforeachdb  @command1="print '?'",  @command2="DBCC CHECKDB (?) "
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
有了上面的分析,我们可以建立自己的sp_MSforeachObject:
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDBUSE MASTER
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
GO
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
CREATE proc sp_MSforeachObject
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB 
@objectType int=1,
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB 
@command1 nvarchar(2000), 
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB 
@replacechar nchar(1= N'?'
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB 
@command2 nvarchar(2000= null,
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB    
@command3 nvarchar(2000= null
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB 
@whereand nvarchar(2000= null,
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB 
@precommand nvarchar(2000= null
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB 
@postcommand nvarchar(2000= null
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
as
GO
这样我们来测试一下: 1.获得所有的存储过程的脚本:
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB         EXEc sp_MSforeachObject @command1="sp_helptext '?' ",@objectType=4
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
2.获得所有的视图的脚本:
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB         EXEc sp_MSforeachObject @command1="sp_helptext '?' ",@objectType=2
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
3.比如在开发过程中,没一个用户都是自己的OBJECT OWNER,所以在真实的数据库时都要改为DBO:
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB           EXEc sp_MSforeachObject @command1="sp_changeobjectowner '?''dbo'",@objectType=1
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB           
EXEc sp_MSforeachObject @command1="sp_changeobjectowner '?''dbo'",@objectType=2
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB           
EXEc sp_MSforeachObject @command1="sp_changeobjectowner '?''dbo'",@objectType=3
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB           
EXEc sp_MSforeachObject @command1="sp_changeobjectowner '?''dbo'",@objectType=4
SQL存储过程 之 sp_MSforeachtable和sp_MSforeachDB
这样就非常方便的将每一个数据库对象改为DBO. 当然还要很多非常好的功能,大家可以自己深入研究吧
原作者Blog:http://blogger.org.cn/blog/blog.asp?subjectid=687&name=yjzhg

相关文章:

  • 2021-11-16
  • 2021-07-07
  • 2021-12-08
  • 2021-11-12
  • 2021-09-29
猜你喜欢
  • 2021-06-17
  • 2021-12-05
  • 2021-11-17
  • 2021-09-28
相关资源
相似解决方案