【推荐】(SqlServer)不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解
?
【推薦】(SqlServer)不公開(kāi)存儲(chǔ)過(guò)程
sp_Msforeachtable與sp_Msforeachdb詳解
——通過(guò)知識(shí)共享樹(shù)立個(gè)人品牌。
?
?
一.簡(jiǎn)要介紹:
系統(tǒng)存儲(chǔ)過(guò)程sp_MSforeachtable和sp_MSforeachdb,是微軟提供的兩個(gè)不公開(kāi)的存儲(chǔ)過(guò)程。從mssql6.5開(kāi)始,存放在SQL Server的MASTER數(shù)據(jù)庫(kù)中??梢杂脕?lái)對(duì)某個(gè)數(shù)據(jù)庫(kù)的所有表或某個(gè)SQL服務(wù)器上的所有數(shù)據(jù)庫(kù)進(jìn)行管理,下面將對(duì)此進(jìn)行詳細(xì)介紹。
作為數(shù)據(jù)庫(kù)管理者或開(kāi)發(fā)者等經(jīng)常會(huì)檢查整個(gè)數(shù)據(jù)庫(kù)或用戶表。
如:檢查整個(gè)數(shù)據(jù)庫(kù)的容量,看指定數(shù)據(jù)庫(kù)所有用戶表的容量,所有表的記錄數(shù)等等,我們一般處理這樣的問(wèn)題都是通過(guò)游標(biāo)來(lái)達(dá)到要求。
如果我們用sp_MSforeachtable就可以非常方便的達(dá)到相同的目的,
如:sql查詢所有用戶表的列表,詳細(xì)信息,如:記錄數(shù),表占用大小等
?
EXEC?sp_MSforeachtable?"EXECUTE?sp_spaceused?'?'"?
二.各參數(shù)說(shuō)明:
??
@command1?nvarchar(2000),??????????--第一條運(yùn)行的SQL指令??@replacechar?nchar(1)?=?N'?',??????--指定的占位符號(hào)
??@command2?nvarchar(2000)=?null,????--第二條運(yùn)行的SQL指令
??@command3?nvarchar(2000)??=?null,??--第三條運(yùn)行的SQL指令
??@whereand?nvarchar(2000)??=?null,??--可選條件來(lái)選擇表
??@precommand?nvarchar(2000)=?null,??--執(zhí)行指令前的操作(類似控件的觸發(fā)前的操作)
??@postcommand?nvarchar(2000)=?null??--執(zhí)行指令后的操作(類似控件的觸發(fā)后的操作)
?以后為sp_MSforeachtable的參數(shù),sp_MSforeachdb不包括參數(shù)@whereand
?我們?cè)?/span>master數(shù)據(jù)庫(kù)里執(zhí)行下面的語(yǔ)句可以看到兩個(gè)proc詳細(xì)的代碼
?
use?masterexec?sp_helptext?sp_MSforeachtable
exec?sp_helptext?sp_Msforeachdb
?
?
三、使用舉例:
???--統(tǒng)計(jì)數(shù)據(jù)庫(kù)里每個(gè)表的詳細(xì)情況:
exec?sp_MSforeachtable?@command1="sp_spaceused?'?'"?
??--獲得每個(gè)表的記錄數(shù)和容量:
??EXEC?sp_MSforeachtable?@command1="print?'?'",
?????????????????????????@command2="sp_spaceused?'?'",
?????????????????????????@command3=?"SELECT?count(*)?FROM???"
?
??--獲得所有的數(shù)據(jù)庫(kù)的存儲(chǔ)空間:
??EXEC?sp_MSforeachdb?@command1="print?'?'",
??????????????????????@command2="sp_spaceused?"
?
??--檢查所有的數(shù)據(jù)庫(kù)
??EXEC?sp_MSforeachdb?@command1="print?'?'",
??????????????????????@command2="DBCC?CHECKDB?(?)?"
?
??--更新PUBS數(shù)據(jù)庫(kù)中已t開(kāi)頭的所有表的統(tǒng)計(jì):
??EXEC?sp_MSforeachtable???@whereand="and?name?like?'t%'",
? ? ? ? ? ? ? ? ? ? ? ? ? ?@replacechar='*',
???????????????????????????@precommand="print?'Updating?Statistics.....'?print?''",
???????????????????????????@command1="print?'*'?update?statistics?*?",
? ? ? ? ? ? ? ? ? ? ? ? ? ?@postcommand=?"print''print?'Complete?Update?Statistics!'"
?
??--刪除當(dāng)前數(shù)據(jù)庫(kù)所有表中的數(shù)據(jù)
??sp_MSforeachtable?@command1='Delete?from??'
??sp_MSforeachtable?@command1?=?"TRUNCATE?TABLE??"
?
--查詢數(shù)據(jù)庫(kù)所有表的記錄總數(shù)
CREATE?TABLE?#temp?(TableName?VARCHAR?(255),?RowCnt?INT)
EXEC?sp_MSforeachtable?'INSERT?INTO?#temp?SELECT?''?'',?COUNT(*)?FROM??'
SELECT?TableName,?RowCnt?FROM?#temp?ORDER?BY?TableName
DROP?TABLE?#temp
?
--檢查數(shù)據(jù)庫(kù)里每個(gè)表或索引視圖的數(shù)據(jù)、索引及text、ntext?和image?頁(yè)的完整性
--下列語(yǔ)句需在單用戶模式下執(zhí)行(sp_dboption?'db_name',?'single?user',?'true')
--,將true改成false就又變成多用戶了
exec?sp_msforeachtable?"dbcc?checktable('?',repair_rebuild)"
?
4.參數(shù)@whereand的用法:
?
?@whereand參數(shù)在存儲(chǔ)過(guò)程中起到指令條件限制的作用,具體的寫(xiě)法如下:
?@whereend,可以這么寫(xiě)
?
@whereand='?AND?o.name?in?(''Table1'',''Table2'',.......)'??
又如:
我想更新Table1/Table2/Table3中NOTE列為NULL的值
?
sp_MSforeachtable?@command1='Update???Set?NOTE=''''?Where?NOTE?is?NULL'? ? ? ? ? ? ? ? ? ,@whereand='?AND?o.name?in?(''Table1'',''Table2'',''Table3'')'
?
5. "?"特別說(shuō)明:
"?"在存儲(chǔ)過(guò)程的特殊用法,造就了這兩個(gè)功能強(qiáng)大的存儲(chǔ)過(guò)程.
? "?"的作用,相當(dāng)于DOS命令中和我們?cè)赪INDOWS下搜索文件時(shí)的通配符的作用。
6.小結(jié)
?有上面的分析,我們可以建立自己的sp_MSforeachObject:(注:下面的內(nèi)容來(lái)源于網(wǎng)上。)
?USE?MASTER
GOCREATE?proc?sp_MSforeachObject
?@objectType?int=1,
?@command1?nvarchar(2000),
?@replacechar?nchar(1)?=?N'?',
?@command2?nvarchar(2000)?=?null,
????@command3?nvarchar(2000)?=?null,
?@whereand?nvarchar(2000)?=?null,
?@precommand?nvarchar(2000)?=?null,
?@postcommand?nvarchar(2000)?=?null
as
?/*?This?proc?returns?one?or?more?rows?for?each?table?(optionally,?matching?@where),?with?each?table?defaulting?to?its
own?result?set?*/
?/*?@precommand?and?@postcommand?may?be?used?to?force?a?single?result?set?via?a?temp?table.?*/
?/*?Preprocessor?won't?replace?within?quotes?so?have?to?use?str().?*/
?declare?@mscat?nvarchar(12)
?select?@mscat?=?ltrim(str(convert(int,?0x0002)))
?if?(@precommand?is?not?null)
??exec(@precommand)
?/*?Defined??@isobject?for?save?object?type?*/
?Declare?@isobject?varchar(256)
?select?@isobject=?case?@objectType?when?1?then?'IsUserTable'
?????????when?2?then?'IsView'
?????????when?3?then?'IsTrigger'
?????????when?4?then?'IsProcedure'
?????????when?5?then?'IsDefault'??
?????????when?6?then?'IsForeignKey'
?????????when?7?then?'IsScalarFunction'
?????????when?8?then?'IsInlineFunction'
?????????when?9?then?'IsPrimaryKey'
?????????when?10?then?'IsExtendedProc'???
?????????when?11?then?'IsReplProc'
?????????when?12?then?'IsRule'
??????????????????end
?/*?Create?the?select?*/
?/*?Use?@isobject?variable?isstead?of?IsUserTable?string?*/
EXEC(N'declare?hCForEach?cursor?global?for?select?''[''?+?REPLACE(user_name(uid),?N'']'',?N'']]'')?+?'']''?+?''.''?+?''[''?+
REPLACE(object_name(id),?N'']'',?N'']]'')?+?'']''?from?dbo.sysobjects?o?'
????????+?N'?where?OBJECTPROPERTY(o.id,?N'''+@isobject+''')?=?1?'+N'?and?o.category?&?'?+?@mscat?+?N'?=?0?'
???????+?@whereand)
?declare?@retval?int
?select?@retval?=?@@error
?if?(@retval?=?0)
??exec?@retval?=?sp_MSforeach_worker?@command1,?@replacechar,?@command2,?@command3
?if?(@retval?=?0?and?@postcommand?is?not?null)
??exec(@postcommand)
?return?@retval
GO
我們來(lái)測(cè)試一下:
?
--獲得所有的存儲(chǔ)過(guò)程的腳本:EXEc?sp_MSforeachObject?@command1="sp_helptext?'?'?",@objectType=4
?
--獲得所有的視圖的腳本:
EXEc?sp_MSforeachObject?@command1="sp_helptext?'?'?",@objectType=2
?
--比如在開(kāi)發(fā)過(guò)程中,沒(méi)一個(gè)用戶都是自己的OBJECT?OWNER,所以在真實(shí)的數(shù)據(jù)庫(kù)時(shí)都要改為DBO:
EXEc?sp_MSforeachObject?@command1="sp_changeobjectowner?'?',?'dbo'",@objectType=1
EXEc?sp_MSforeachObject?@command1="sp_changeobjectowner?'?',?'dbo'",@objectType=2
EXEc?sp_MSforeachObject?@command1="sp_changeobjectowner?'?',?'dbo'",@objectType=3
EXEc?sp_MSforeachObject?@command1="sp_changeobjectowner?'?',?'dbo'",@objectType=4
?
總結(jié)
以上是生活随笔為你收集整理的【推荐】(SqlServer)不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 长的帅不是你的错,长的没特点就不应该了
- 下一篇: 远程断点调试不需要跟时间赛跑