[翻译]SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb

SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb

您是否曾经写过代码来处理数据库中的所有表?处理一个 SQL Server实例中的所有数据库的代码又该如何写?然则,您是否知道有多种方法可以解决这问题?您可以创建一个游标cursor包含所有数据表,或者包含SQL Server实例的所有数据库;或者使用非公开(undocumented)的存储过程。本文将向您阐述非公开的存储过程的工作方式,以及应用实例向您展示如何使用它们。非公开的存储过程比之游标更易用。

概述

Microsoft 提供了两个非公开化的存储过程,让您可以迭代处理数据库中的所有表,或者SQL Server 实例中的所有数据库。第一个存储过程是"sp_MSforeachtable",让您可以轻易地使用代码处理数据库中的所有表;另一个是"sp_MSforeachdb",处理SQL Server 实例中的所有数据库。让我们深入地了解这两个存储过程。

sp_MSforeachtable

"sp_MSforeachtable"没有在在线文档中出现,它存在于master数据库中,可以对给定数据库的所有表执行单条或多条T-SQL命令,请看下面的例子。

假如,您需要创建一个临时表,记录当前数据库拥有的表的表名、行记录数。为了实现此功能,您需要执行这样的命令:"select '<mytable>', count(*) from <mytable>"。其中"<mytable>"替换为数据库中的每个表名,并将结果插入到临时表。下面我们用游标与非公开的"sp_MSforeachtable"来分别实现。

使用游标的方式:

下面是输出结果:

下面代码应用非公开的"sp_MSforeachtable"生成相同的结果:

下面是结果:

可见,使用游标与sp_MSforeachtable可生成相同的结果,您认为哪种方式更具可读性,更简单?下面来详细介绍sp_MSforeachtable的语法:

exec @RETURN_VALUE=sp_MSforeachtable @command1, @replacechar, @command2,

@command3, @whereand, @precommand, @postcommand

说明:

  • @RETURN_VALUE – 返回值
  • @command1 – 类型是nvarchar(2000),sp_MSforeachtable最先执行的命令
  • @replacechar – 处理过程中,将命令行的这个字符替换为具体的表名(默认是"?")
  • @command2\@command3:对每个数据表,都会执行这两条命令,@command2在@command1之后执行,@command3在@command2之后执行
  • @whereand – 类型是varchar(2000),提供额外的约束来过滤 sysobjects 表的行
  • @precommand - 类型是varchar(2000),在处理任何表之前执行此命令
  • @postcommand - 类型是varchar(2000),在处理完所有表之后执行此命令

下面几个例子演示此存储过程的用法,处理所有表或者部分表。

下面查询以字母 p 开头的表,使用参数 @whereand 设置过滤条件,代码如下:

下面是结果:

上面的代码使用了参数 @command1 与 @whereand,参数 @whereand 用来设置 WHERE 条件,筛选出以字母 p 开头的表名,我设置了参数值为"and o.name like ''p%''"。如果您希望使用多个条件约束,如以 p 开头或者以 a 开头,设置参数值为:

and o.name like ''p%'' or o.name like ''a%''

 

如果语句有问题,将 name 的前缀去掉,如下:

 

and name like ''p%'' or name like ''a%''

 

注意,上面例子的参数 @command1 使用了"?",它叫做替换字符(replacement character),默认被所有表名替换。如果您需要在命令中使用"?"作为内容而不是被表名替换的替换字符,那么可以使用参数 @replacechar 来设置替换字符。下面例子使用"{"作为替换字符。

下面是结果:

还有两个参数 @precommand 与 @postcommand,看下面例子,把上面例子中的所有语句整合为一个简洁的存储过程调用。

注意上面例子用了全局临时表 ##rowcount,如果用临时表 #rowcount会报错。参数 @precommand 创建全局临时表,只执行了一次,并先于 @command1 的语句执行。@postcommmand 的语句待迭代处理完所有表后执行,也仅执行一次,用于显示结果并删除临时表。

 

sp_MSforeachdb

sp_MSforeachdb 同样也是在 master 数据库中,它迭代SQL Server 实例中的每个数据库,以执行T-SQL 语句,如"DBCCCHECKDB",在看看它的语法

exec @RETURN_VALUE = sp_MSforeachdb @command1, @replacechar,

@command2, @command3, @precommand, @postcommand

说明:

  • @RETURN_VALUE – 返回值
  • @command1 – 类型是 nvarchar(2000),最先执行的命令
  • @replacechar – 替换字符,命令字符串中被替换为实际的数据库名(默认是"?")
  • @command2\@command3:对每个数据库,都会执行这两条命令,@command2在@command1之后执行,@command3在@command2之后执行
  • @precommand - 类型是varchar(2000),在处理任何数据库之前执行此命令
  • @postcommand - 类型是varchar(2000),在处理完所有数据库之后执行此命令

sp_MSforeachdb 的参数与sp_MSforeachtable 的参数类似,因此,不再特意介绍这些参数。

请看下面的简单例子,此例子将进行数据库备份,然后对每个数据库做"DBCC CHECKDB":

这里我用了三条不同的命令,第一条打印正在处理的数据库名。sp_MSforeachtable 有一个参数用来过滤需要处理的数据表,但是sp_MSforeachdb没有类似的过滤参数。由于SQL Server 不支持对 tempdb 的备份,因此我要跳过tempdb,这是我在每条命令使用 IF 的原因。第二条命令进行数据库备份,最后一条命令对除 tempdb 之外的数据库运行"DBCC CHECKDB"。

运行上面命令之前要先创建目录"c:\temp",下面是部分输出结果:

 

使用SQL Server非公开存储过程的说明

当使用这些非公开的存储过程时您须小心,并进行测试。由于未公开,意味着Microsoft在任何版本的升级或者补丁包都可能对它们进行修改,并且不做任何告知。因此,您需要在所有的SQL Server版本做全面的测试,测试以验证您的代码是否在新版本中仍然正常运行。

结语

正如您所见,这两个非公开的存储过程比游标易用,以后您可以用它们来迭代处理数据表或数据库。但是请谨记,这两个存储过程是非公开的,Microsoft很可能会随时改变它们的功能。

参考

SQL Server Undocumented Stored Procedures sp_MSforeachtable and sp_MSforeachdb

sp_MSforeachtable

 

转载于:https://www.cnblogs.com/feixian49/archive/2011/05/10/2042733.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持

Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持&#xff0c;下面关于Java反射的描述&#xff0c;哪些是错误的&#xff1a;( ) A Java反射主要涉及的类如Class, Method, Filed,等&#xff0c;他们都在java.lang.reflet包下 B 通…

sqlserver关键字

ROWCOUNT Transact-SQL 语句可以通过下列方式设置 ROWCOUNT 的值&#xff1a; 将 ROWCOUNT 设置为受影响或被读取的行的数目。可以将行发送到客户端&#xff0c;也可以不发送。 保留前一个语句执行中的 ROWCOUNT。将 ROWCOUNT 重置为 0 但不将该值返回到客户端。 执行简单分配的…

linux 执行sh 文件是遇到找不到cd '目录'

在linux中将多个php命令写到同一个sh文件中执行 #!/bin/bash/ cd /www/sf/ /usr/local/bin/php xxx.php /usr/local/bin/php xxx1.php /usr/local/bin/php xxx2.php 然后执行命令 sh xxx.sh 有的时候会出现 找不到/www/sf/目录 为什么呢&#xff0c;找了下资料&#xff0c;是…

Asp.Net Session 丢失的奇怪问题,求救!

Asp.Net Session 丢失的奇怪问题&#xff0c;求救我遇到一个很奇怪的 asp.net 问题&#xff0c;我有三个页面&#xff1a;login.aspx &#xff1a;实现输入帐号密码&#xff0c;将帐号&#xff08;yh &#xff1a;用户&#xff09;及权限 ( js_id &#xff1a;角色ID) 保存为 s…

java面试题23 牛客ArrayLists和LinkedList的区别,下述说法正确的有?

java面试题23 牛客ArrayLists和LinkedList的区别&#xff0c;下述说法正确的有&#xff1f; A ArrayList是实现了基于动态数组的数据结构&#xff0c;LinkedList基于链表的数据结构。 B 对于随机访问get和set&#xff0c;ArrayList觉得优于LinkedList&#xff0c;因为LinkedL…

制作特殊字的脚本

<html> <head> <title>特殊文字的制作</title> <meta http-equiv"Content-Type" content"text/html; charsetgb2312"> </head> <body text#00ff00 bgColorblack οnlοade(d.q)> <center>特殊文字的制作…

cursor.execute(sql) 执行结果集是有记录的 但是num=cursor.rownumber 返回值为0

开始cursor.execute(.join(str(sql).strip())) #count cursor.rowcount; numcursor.rownumber修改后&#xff1a;cursor.execute(.join(str(sql).strip())) cursor.fetchall(); #count cursor.rowcount; numcursor.rownumber print(---------------) print (cursor.rownumber) …

Java Web 应用概述

1、java Web 应用是建立在java语言基础上的企业web应用系统&#xff0c;oracle公司根据行业发展和便于开发制定了一套规范&#xff1a;Java EE规范&#xff0c;截至到当前&#xff08;2016.3.11&#xff09;是java EE7规范&#xff0c;其中包括大家常见的Java Servlet 、JavaSe…

java面试题24 关于Java中的数组,

java面试题24 关于Java中的数组&#xff0c;下面的一些描述&#xff0c;哪些描述是准确的&#xff1a;&#xff08; &#xff09; A 数组是一个对象&#xff0c;不同类型的数组具有不同的类 B 数组长度是可以动态调整的 C 数组是一个连续的存储结构 D:一个固定长度的…

[开发技巧3]不显示报表直接打印

水晶报表9.2VB6 使用Application可以进行打印 在将数据赋给报表模板后&#xff0c;调用PrintOut方法 赋给报表数据objCRReport.Database.SetDataSource rst 此句打印&#xff0c;会出现打印提示框objCRReport.PrintOut 不提示&#xff0c;直接打印到默认打印机CallobjCRReport.…

python中cursor操作数据库(转)

原文出处&#xff1a;http://doudouclever.blog.163.com/blog/static/175112310201284115340663/python 操作数据库&#xff0c;要安装一个Python和数据库交互的包MySQL-python-1.2.2.win32-py2.5.exe&#xff0c;然后我们就可以使用MySQLdb这个包进行数据库操作了。 操作步…

java面试题25 在程序代码中写的注释太多,会使编译后的程序尺寸变大。

java面试题25 在程序代码中写的注释太多&#xff0c;会使编译后的程序尺寸变大。 A:正确 B:错误 蒙蔽树上蒙蔽果&#xff0c;蒙蔽树下你和我 拿到这道题&#xff0c;我觉得说的贼有道理&#xff0c;注释太多&#xff0c;尺寸变大。无疑与就和驾考 一样&#xff0c;遇到路人…

implicit request ?

不了解或不會Action在play framework很難再深入下去, 這是http request的點 以下這段代碼困擾我很久, 如今我才剛了解 Action { implicit request >Ok("Got request [" request "]") } 原文這麼說 It is often useful to mark the request parameter …

SQL开发中容易忽视的一些小地方( 三)

目的&#xff1a;这篇文章我想说说我在工作中关于in和union all 的用法. 索引定义 &#xff1a; 微软的SQL SERVER提供了两种索引&#xff1a;聚集索引(clustered index&#xff0c;也称聚类索引、簇集索引)和非聚集索引(nonclustered index&#xff0c;也称非聚类索引、非簇集…

java面试题26 java语言的下面几种数组复制方法中,哪个效率最高?

java面试题26 java语言的下面几种数组复制方法中&#xff0c;哪个效率最高&#xff1f; A for 循环逐一复制 B System.arraycopy C Array.copyOf D 使用clone方法 效率&#xff1a;System.arraycopy > clone > Arrays.copyOf > for循环 1、System.arraycopy的用法…

pycharm使用笔记2-远程连接(转)

原文地址:https://blog.csdn.net/jinxiaonian11/article/details/70208920 随着科技的发展&#xff0c;远程办公已经是一种趋势&#xff0c;远程开发能力对于每一个程序员来说都是必不可少的。有时候就算在公司&#xff0c;在进行开发的时候有许多的数据都是储存在服务器上的&a…

第三章 使用属性升级MyBank

1、C#中的访问修饰符&#xff1a; a) public 【公共的】访问不受到任何限制&#xff0c;级别最高。一般用于修饰方法&#xff0c;提供给其他类调用。 b) private 【私有的】只有类的内部可以使用&#xff0c;一般用于修饰字段&#xff0c;保证数据的安全性。 注&#xff1a;如果…

java面试题27 java中下面哪些是Object类的方法()

java面试题27 java中下面哪些是Object类的方法&#xff08;&#xff09; A notify() B notifyAll() C sleep() D wait() 蒙蔽树上蒙蔽果&#xff0c;蒙蔽树下你和我。遇到这种题&#xff0c;我默默的打开了编译工具 Object类中方法&#xff1a; protected Object clone()…

HK-2000 数采仪系统说明之 7.HK7710 DTU 简单配置说明

DTU配置列表: 1 移动服务中心设置(MSC) 2 终端单元设置 3 网络通道设置 4 用户串口设置 移动服务中心设置(MSC) 一般默认&#xff0c;当需要连接的网络是APN网络是需要配置&#xff0c;该项下的APN接入点信息 MSC设置列表: 1 服务代码 2 P…

shiro学习(1):shiro简介

Apache Shiro是Java的一个安全框架。对比另一个安全框架Spring Sercurity&#xff0c;它更简单和灵活。 Shiro可以帮助我们完成&#xff1a;认证、授权、加密、会话管理、Web集成、缓存等。 Apache Shiro特性 Authentication&#xff1a;身份认证/登录&#xff0c;验证用户是…