非文档化存储过程(XP_FileExist、SP_MSForEachDb等)
--原帖地址:http://www.sqlservercentral.com/articles/Stored+Procedures/62868/
--牙膏皮翻译整理,转贴请注明出自微软BI开拓者www.windbi.com
介绍:
在SQL Server 2005中,我们能够发现很多有用的非文档系统存储过程(system stored procedures)和扩展存储过程(extended stored procedures)。正因为它们是非文档的,所以需要谨慎的使用它们。也许在下一个版本或者补丁包中,它们就会被删除或修改。如果遇到需要应用到今后的SQL Server版本的核心代码时,避免使用这些非文档存储过程才是明智的。当不需要考虑未来版本的时候,使用它们带来的好处将远远大于风险。
XP_FileExist
用法:EXEC xp_fileexist <filename> [, <file_exists INT> OUTPUT]
如果在没有提供OUTPUT参数的情况下执行该语句,它将返回三列信息,包括文件是否存在、文件是否是目录以及该文件的父目录是否存在。例如:
exec master.dbo.xp_fileexist 'C:\temp'
返回结果:
| xp_fileexist Output
|
File Exists
| File is a Directory
| Parent Directory Exists
|
0
| 1
| 1
|
如果指定了OUTPUT参数,这执行结果将返回一个值给这个参数,如果这个文件存在,则参数为1,否则为0,如果返回为0说明该文件名是一个目录。
通常,最好是调用这个T-SQL脚本检查任何文件是否存在,在T-SQL脚本中也确实很方便就能做到。你还可以利用xp_cmdshell来使得这个语法结构变得更加实用。
SP_MSForEachDb
sp_msforeachdb将执行对每一个服务器上的数据库连接字符串命令。任何问号(?),在该字符串将改为每一个数据库的名称。它可以用于查找数据库实例上给定的表。例如:
exec dbo.sp_MSforeachdb 'select ''?'', * from [?].INFORMATION_SCHEMA.TABLES where table_name like ''authors'' '
将找到实例中每一个名为authors的表。它也能用在维护计划中。例如:
Exec dbo.sp_Msforeachdb ‘DBCC SHRINKDATABASE(N’’?’’)’
将收缩实例中的每一个数据库。值得注意的是,在一个精心设计的生产系统运行该命令不会是一个好主意,但它可用于回收测试和开发服务器文件空间并且有更多的好处可以在需要的时候执行。
SP_MSForEachTable
Sp_msforeachtable和sp_msforeachdb非常相似,除了这个命令是针对数据库中的每个表。例如,如果在一个测试数据库中并且需要将所有的表里的数据都清空,仅保留表结构,这个命令可以这样写:Exec dbo.sp_msforeachtable ‘delete test.dbo.[?]’
SP_who2
Sp_who2就像sp_who的大哥。它的功能非常近似sp_who,除了列名有些不同、ecid列被删除、增加了一些列。它增加了cputime,diskio,lastbatch以及由sp_who提供的程序名。输出如下:
| sp_who2 output
|
SPID
| Status
| Login
| HostName
| BlkBy
| DBName
| Command
| CPUTime
| DiskIO
| LastBatch
| ProgramName
| SPID
| REQUESTID
|
1
| BACKGROUND
| sa
| .
| .
| NULL
| RESOURCE MONITOR
| 100
| 0
| 04/12 15:58:54
|
| 1
| 0
|
2
| BACKGROUND
| sa
| .
| .
| NULL
| LAZY WRITER
| 10
| 0
| 04/12 15:58:54
|
| 2
| 0
|
3
| SUSPENDED
| sa
| .
| .
| NULL
| LOG WRITER
| 0
| 0
| 04/12 15:58:54
|
| 0
| 0
|
4
| BACKGROUND
| sa
| .
| .
| NULL
| LOCK MONITOR
| 0
| 0
| 04/12 15:58:54
|
| 4
| 0
|
Sp_who和sp_who2里很多增加的列在程序和脚本中都是极其有用,但是在特殊场合用图形界面的活动跟踪程序会更方便。
Sp_MSdependencies
Sp_msdependencies是一个强大的过程,它能用来确定一个对象在数据库中的所有依赖关系。用法如下:
exec dbo.sp_MSdependencies [<object name> ] , [<object type>], [<Flags>], [<objlist>]
这个过程也接受一个整型变量@intrans,但是什么也不做。所有的变量都是可选的并且大多数情况下都不用同时提供对象名和对象类型。如果exec sp_msdependencies '?'被执行,它将提供详细的用法。
Sp_MSdependencies和文档化存储过程sp_depends是相似的,但是同时它更灵活也更难用。Sp_depends将返回两个结果集,第一个是目标对象依赖的对象,第二个显示被目标对象依赖的对象,并且这两种都不考虑外键依赖。换句话说Sp_MSdependecies考虑了外键关系并准确的返回相关信息。默认情况下,它不会返回系统表、内部对象或用户自定义数据类型,但是它能够通过flags切换。返回的结果集也与sp_depends不同。
如果只有个一个对象名,它将返回每一个关于这个对象的依赖关系。例如:Exec sp_msdependecies ‘dbo.titleview’在pubs数据库中执行,返回
| sp_msdependencies output
|
oType
| oObjName
| oOwner
| oSequence
|
8
| authors
| dbo
| 1
|
8
| publishers
| dbo
| 1
|
8
| titles
| dbo
| 2
|
8
| titleauthor
| dbo
| 3
|
上面的表说明dbo.titleview依赖authors,titles和titleauthor尽管authors依赖publishers表。Otype为8说明他们是tables。
假如只有对象类型将得到当前数据库中每一个对象直接依赖和间接依赖关系。在pubs库中,dbo.titleview是唯一的视图,所以如果视图被选择并且执行Exec sp_msdependecies NULL,2
结果将是:
oType oObjName oOwner oSequence----------- ------------------------ ------------------------------- ---------8 authors dbo 18 publishers dbo 18 titles dbo 28 titleauthor dbo 34 titleview dbo 4
这里显示了每一个依赖关系,包括这个视图自己。
这个标记能增强对象名或对象类型,并且他们肯定能准确返回。这个标记参数是一个十六进制位图。它能准确控制返回的对象类型以及孩子或对象依赖的目标,而不是父亲或目标依赖的对象。用这个标记能返回系统对象和用户自定义数据类型,通常这些是被忽略的。它还能返回关系级别,这点更像sp_depends。例如:为了寻找titles表依赖的对象:
Exec sp_msdependecies ‘titles’,NULL,0x401fd
返回结果:
| sp_msdependencies output
|
oType
| oObjName
| oOwner
| oSequence
|
8
| roysched
| dbo
| 1
|
8
| sales
| dbo
| 1
|
8
| titleauthor
| dbo
| 1
|
16
| reptq1
| dbo
| 1
|
16
| reptq2
| dbo
| 1
|
16
| reptq3
| dbo
| 1
|
4
| titleview
| dbo
| 2
|
16
| byroyalty
| dbo
| 2
|
每一行都是titles表的直接或间接依赖。例如,程序byroyalty并不直接依赖titles表,但它用到了titleview,而titleview相应的依赖titles表。
通常在必要的时候,在SSMS中能更方便和友好的通过图形化界面展示依赖关系信息,但是sp_msdepencies能提供更有价值的信息,如果要考虑外键和间接依赖关系的时候,sp_depends就显得力不从心了。
结论
非文档化的存储过程在使用过程中应该小心谨慎,尤其是从一个版本的SQL Server到另一个版本来执行这个存储过程的时候。非文档化存储过程更像是在他们的文档化存储过程中做了一些更改,并且在技术上不属于官方支持的范围。考虑到这些风险,他们通常会非常有用。这里提供了一些有用的例子以及在SQL Server 2005中如何使用。(翻译得有点惨目忍睹啊…… o_o!!)