Sp_MSForEachTable和sp_MSForEachDb是SQL Server的兩個系統預存程序,存在於Master資料庫當中,但是在SQL Server的線上說明中並沒有這兩個預存程序,也就是說微軟並沒有把這兩個預存程序編進SQL Server的聯機叢書中。那麼Microsoft設計這兩個系統預存程序的目的到底是什麼呢?這兩個系統預存程序又能幹些什麼呢?實際上Microsoft設計這兩個系統預存程序的目的是要支援編寫一種單一的SQL語句,該語句可以在當前伺服器的所有資料庫上或當前資料庫的所有表上執行相同的動作。下面介紹這兩個預存程序。
首先看下這條SQL語句:exec sp_MSForEachDb @Command1 = “print ‘?’” ,該SQL語句從當前伺服器中的所有的資料名稱。執行結果
@Command1參數用於指定預存程序將在每個資料庫上執行的動作。這裡使用問號代替了資料庫名稱,該預存程序最多可以指定三個命令(使用@Command2 、@Command3)。在後台,這個預存程序將在sysdatabases表中為每一條記錄開啟一個遊標,然後動態組裝一個將通過迴圈在每條記錄上執行的批處理。這條語句將顯示每個資料庫中的使用者表的數目:exec sp_MSForEachDb @Command1 = "select count(name) from ?.dbo.sysobjects where xtype='U'",執行結果
下面的命令建立了一個有關每個資料庫空間使用方式的報告:exec sp_MSForEachDb @Command1 = "use ? exec sp_Spaceused",執行結果
更為有趣的是可以在當前資料庫的所有表上運行sp_spaceused過程:exec sp_MSForEachtable @Command1 = "sp_Spaceused '?'",你也可以在每一個表上得到一些記錄:exec sp_MSForEachtable @Command1 = "print '?'",@Command2 = "select count(*) from ?",執行結果並沒有按照所希望的順序排列,如果你想按照表名對它進行排列,必須使用@whereand參數:exec sp_MSForEachtable @Command1 = "exec sp_Spaceused '?'",@whereand = " order by name",這個參數本來是用來添加where子查詢用的,但是因為查詢時動態組裝的,所以你可以借用一下來加入一個Order by子句。
再給你偷一個小竅門,也就是如果一個命令在迴圈之前或之後只應該執行一次,那麼你可以使用@precommand或@postcommand參數;還有你也還可以使用@replacechar參數來為資料庫名稱和表名指定不同的預留位置,這個參數在命令需要使用問號時十分有用,例如,Like子句中的萬用字元等。
以前,在檢查所有資料庫的容量;看看指定資料庫所有使用者表的容量,所有表的記錄數等工作時需要寫一些遊標來完成這些工作,不但費勁費時,而且遊標的效率也不高,好了,有了這兩個預存程序,你就可以輕而易舉完成這些工作了。大家感興趣的話,可以去看看這兩個預存程序的原始碼,這裡就不再把它貼出來了。