[翻译]SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb
SQL Server 未公開(kāi)的兩個(gè)存儲(chǔ)過(guò)程sp_MSforeachtable 和 sp_MSforeachdb
您是否曾經(jīng)寫過(guò)代碼來(lái)處理數(shù)據(jù)庫(kù)中的所有表?處理一個(gè) SQL Server實(shí)例中的所有數(shù)據(jù)庫(kù)的代碼又該如何寫?然則,您是否知道有多種方法可以解決這問(wèn)題?您可以創(chuàng)建一個(gè)游標(biāo)cursor包含所有數(shù)據(jù)表,或者包含SQL Server實(shí)例的所有數(shù)據(jù)庫(kù);或者使用非公開(kāi)(undocumented)的存儲(chǔ)過(guò)程。本文將向您闡述非公開(kāi)的存儲(chǔ)過(guò)程的工作方式,以及應(yīng)用實(shí)例向您展示如何使用它們。非公開(kāi)的存儲(chǔ)過(guò)程比之游標(biāo)更易用。
概述
Microsoft 提供了兩個(gè)非公開(kāi)化的存儲(chǔ)過(guò)程,讓您可以迭代處理數(shù)據(jù)庫(kù)中的所有表,或者SQL Server 實(shí)例中的所有數(shù)據(jù)庫(kù)。第一個(gè)存儲(chǔ)過(guò)程是"sp_MSforeachtable",讓您可以輕易地使用代碼處理數(shù)據(jù)庫(kù)中的所有表;另一個(gè)是"sp_MSforeachdb",處理SQL Server 實(shí)例中的所有數(shù)據(jù)庫(kù)。讓我們深入地了解這兩個(gè)存儲(chǔ)過(guò)程。
sp_MSforeachtable
"sp_MSforeachtable"沒(méi)有在在線文檔中出現(xiàn),它存在于master數(shù)據(jù)庫(kù)中,可以對(duì)給定數(shù)據(jù)庫(kù)的所有表執(zhí)行單條或多條T-SQL命令,請(qǐng)看下面的例子。
假如,您需要?jiǎng)?chuàng)建一個(gè)臨時(shí)表,記錄當(dāng)前數(shù)據(jù)庫(kù)擁有的表的表名、行記錄數(shù)。為了實(shí)現(xiàn)此功能,您需要執(zhí)行這樣的命令:"select '<mytable>', count(*) from <mytable>"。其中"<mytable>"替換為數(shù)據(jù)庫(kù)中的每個(gè)表名,并將結(jié)果插入到臨時(shí)表。下面我們用游標(biāo)與非公開(kāi)的"sp_MSforeachtable"來(lái)分別實(shí)現(xiàn)。
使用游標(biāo)的方式:
下面是輸出結(jié)果:
下面代碼應(yīng)用非公開(kāi)的"sp_MSforeachtable"生成相同的結(jié)果:
下面是結(jié)果:
可見(jiàn),使用游標(biāo)與sp_MSforeachtable可生成相同的結(jié)果,您認(rèn)為哪種方式更具可讀性,更簡(jiǎn)單?下面來(lái)詳細(xì)介紹sp_MSforeachtable的語(yǔ)法:
exec @RETURN_VALUE=sp_MSforeachtable @command1, @replacechar, @command2,
@command3, @whereand, @precommand, @postcommand
說(shuō)明:
- @RETURN_VALUE – 返回值
- @command1 – 類型是nvarchar(2000),sp_MSforeachtable最先執(zhí)行的命令
- @replacechar – 處理過(guò)程中,將命令行的這個(gè)字符替換為具體的表名(默認(rèn)是"?")
- @command2\@command3:對(duì)每個(gè)數(shù)據(jù)表,都會(huì)執(zhí)行這兩條命令,@command2在@command1之后執(zhí)行,@command3在@command2之后執(zhí)行
- @whereand – 類型是varchar(2000),提供額外的約束來(lái)過(guò)濾 sysobjects 表的行
- @precommand - 類型是varchar(2000),在處理任何表之前執(zhí)行此命令
- @postcommand - 類型是varchar(2000),在處理完所有表之后執(zhí)行此命令
下面幾個(gè)例子演示此存儲(chǔ)過(guò)程的用法,處理所有表或者部分表。
下面查詢以字母 p 開(kāi)頭的表,使用參數(shù) @whereand 設(shè)置過(guò)濾條件,代碼如下:
下面是結(jié)果:
上面的代碼使用了參數(shù) @command1 與 @whereand,參數(shù) @whereand 用來(lái)設(shè)置 WHERE 條件,篩選出以字母 p 開(kāi)頭的表名,我設(shè)置了參數(shù)值為"and o.name like ''p%''"。如果您希望使用多個(gè)條件約束,如以 p 開(kāi)頭或者以 a 開(kāi)頭,設(shè)置參數(shù)值為:
and o.name like ''p%'' or o.name like ''a%''
?
如果語(yǔ)句有問(wèn)題,將 name 的前綴去掉,如下:
?
and name like ''p%'' or name like ''a%''
?
注意,上面例子的參數(shù) @command1 使用了"?",它叫做替換字符(replacement character),默認(rèn)被所有表名替換。如果您需要在命令中使用"?"作為內(nèi)容而不是被表名替換的替換字符,那么可以使用參數(shù) @replacechar 來(lái)設(shè)置替換字符。下面例子使用"{"作為替換字符。
下面是結(jié)果:
還有兩個(gè)參數(shù) @precommand 與 @postcommand,看下面例子,把上面例子中的所有語(yǔ)句整合為一個(gè)簡(jiǎn)潔的存儲(chǔ)過(guò)程調(diào)用。
注意上面例子用了全局臨時(shí)表 ##rowcount,如果用臨時(shí)表 #rowcount會(huì)報(bào)錯(cuò)。參數(shù) @precommand 創(chuàng)建全局臨時(shí)表,只執(zhí)行了一次,并先于 @command1 的語(yǔ)句執(zhí)行。@postcommmand 的語(yǔ)句待迭代處理完所有表后執(zhí)行,也僅執(zhí)行一次,用于顯示結(jié)果并刪除臨時(shí)表。
?
sp_MSforeachdb
sp_MSforeachdb 同樣也是在 master 數(shù)據(jù)庫(kù)中,它迭代SQL Server 實(shí)例中的每個(gè)數(shù)據(jù)庫(kù),以執(zhí)行T-SQL 語(yǔ)句,如"DBCCCHECKDB",在看看它的語(yǔ)法
exec @RETURN_VALUE = sp_MSforeachdb @command1, @replacechar,
@command2, @command3, @precommand, @postcommand
說(shuō)明:
- @RETURN_VALUE – 返回值
- @command1 – 類型是 nvarchar(2000),最先執(zhí)行的命令
- @replacechar – 替換字符,命令字符串中被替換為實(shí)際的數(shù)據(jù)庫(kù)名(默認(rèn)是"?")
- @command2\@command3:對(duì)每個(gè)數(shù)據(jù)庫(kù),都會(huì)執(zhí)行這兩條命令,@command2在@command1之后執(zhí)行,@command3在@command2之后執(zhí)行
- @precommand - 類型是varchar(2000),在處理任何數(shù)據(jù)庫(kù)之前執(zhí)行此命令
- @postcommand - 類型是varchar(2000),在處理完所有數(shù)據(jù)庫(kù)之后執(zhí)行此命令
sp_MSforeachdb 的參數(shù)與sp_MSforeachtable 的參數(shù)類似,因此,不再特意介紹這些參數(shù)。
請(qǐng)看下面的簡(jiǎn)單例子,此例子將進(jìn)行數(shù)據(jù)庫(kù)備份,然后對(duì)每個(gè)數(shù)據(jù)庫(kù)做"DBCC CHECKDB":
這里我用了三條不同的命令,第一條打印正在處理的數(shù)據(jù)庫(kù)名。sp_MSforeachtable 有一個(gè)參數(shù)用來(lái)過(guò)濾需要處理的數(shù)據(jù)表,但是sp_MSforeachdb沒(méi)有類似的過(guò)濾參數(shù)。由于SQL Server 不支持對(duì) tempdb 的備份,因此我要跳過(guò)tempdb,這是我在每條命令使用 IF 的原因。第二條命令進(jìn)行數(shù)據(jù)庫(kù)備份,最后一條命令對(duì)除 tempdb 之外的數(shù)據(jù)庫(kù)運(yùn)行"DBCC CHECKDB"。
運(yùn)行上面命令之前要先創(chuàng)建目錄"c:\temp",下面是部分輸出結(jié)果:
?
使用SQL Server非公開(kāi)存儲(chǔ)過(guò)程的說(shuō)明
當(dāng)使用這些非公開(kāi)的存儲(chǔ)過(guò)程時(shí)您須小心,并進(jìn)行測(cè)試。由于未公開(kāi),意味著Microsoft在任何版本的升級(jí)或者補(bǔ)丁包都可能對(duì)它們進(jìn)行修改,并且不做任何告知。因此,您需要在所有的SQL Server版本做全面的測(cè)試,測(cè)試以驗(yàn)證您的代碼是否在新版本中仍然正常運(yùn)行。
結(jié)語(yǔ)
正如您所見(jiàn),這兩個(gè)非公開(kāi)的存儲(chǔ)過(guò)程比游標(biāo)易用,以后您可以用它們來(lái)迭代處理數(shù)據(jù)表或數(shù)據(jù)庫(kù)。但是請(qǐng)謹(jǐn)記,這兩個(gè)存儲(chǔ)過(guò)程是非公開(kāi)的,Microsoft很可能會(huì)隨時(shí)改變它們的功能。
參考
SQL Server Undocumented Stored Procedures sp_MSforeachtable and sp_MSforeachdb
sp_MSforeachtable
?
轉(zhuǎn)載于:https://www.cnblogs.com/feixian49/archive/2011/05/10/2042733.html
總結(jié)
以上是生活随笔為你收集整理的[翻译]SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: win7NVIDIA显卡驱动升级时卡住
- 下一篇: (转)分布式锁的几种使用方式(redis