日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

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

發布時間:2023/12/10 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [翻译]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

總結

以上是生活随笔為你收集整理的[翻译]SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。