一、一般存儲過程
1、信息查看類
1.1、查看系統對象
過程名 |
系統表或視圖 |
描述 |
sp_helpserver |
sysservers |
查看所有服務器信息 |
sp_helpdb |
sysdatabases |
查看所有數據庫信息,如:名稱、大小 |
sp_helplogins |
syslogins |
查看所有數據庫用戶登錄信息 |
sp_helpuser |
sysusers |
查看當前數據庫用戶和角色信息 |
sp_helprole |
sysusers |
查看當前數據庫用戶和角色信息 |
sp_helprolemember |
sysmembers |
返回有關當前數據庫中某個角色的成員的信息 |
sp_helpsrvrolemember |
spt_values |
固定服務器角色成員的信息 |
sp_helpremotelogin |
sysremotelogins |
查看遠端數據庫用戶登錄信息 |
sp_helplinkedsrvlogin |
sysservers |
查看鏈接服務器的登錄 |
sp_helprotect |
sysprotects |
查看當前數據庫下,對象級用戶權限 |
sp_helpindex |
sysindexes |
查看當前數據庫下某個數據對象的索引信息 |
sp_helpconstraint |
sysconstraints |
查看當前數據庫下某個數據對象的的約束信息 |
sp_stored_procedures |
sysobjects |
查看當前數據庫裏所有的存儲過程和函數 |
sp_tables |
sysobjects |
查看當前數據庫下所有的表 |
sp_helptext |
syscomments |
查看當前存儲過程和函數的源代碼 |
sp_configure |
sysconfigures |
用戶設置的每個配置選項在表中各佔一行 |
sp_dboption |
spt_values |
顯示或更改數據庫選項 |
sp_helpfile |
sysfiles |
數據庫中的每個文件在表中佔一行 |
sp_helpfilegroup |
sysfilegroups |
數據庫中的每個文件組在表中佔一行 |
注:
(1)幾乎所有sp_help系列的存儲過程都有對應的系統表或視圖,往往通過過程返回的結果集比系統表或視圖更直觀,但存儲過程返回的結果集並不方便使用select操作;
(2)在調用sp打頭的存儲過程時,SQL SERVER會默認先去master庫中查找,如果不存在再回到當前庫中找,這就是爲什麼當前庫中沒有以上過程,而我們仍然可以直接運行,同樣在自定義存儲過程時,最好不要以sp打頭,因爲這樣就多了一次到master中查找的運行成本;
(3)SQL SERVER服務相關的系統過程都在master庫中,如:各種ADD、DROP、CHANGE、HELP類的系統過程,另外master庫中還有基於DLL實現的擴展存儲過程;
SQL Agent服務相關的系統過程都在msdb庫中,如:作業、維護計劃、日誌傳送、複製等。
1.2、查看某數據庫下表的行數和使用空間信息
sp_spaceused @objname
注:
(1)該過程根據sysindexes表中的信息返回結果,但由於統計信息的更新不及時,可能會有不精確的地方,可以DBCC UPDATEUSAGE來更新sysindexes表中的統計;
1.3、查看數據庫裏用戶和進程的信息
sp_who/sp_who2
注:
(1)查看SQL Server數據庫裏的活動用戶和進程的信息
sp_who 'active'
(2)推薦使用網友改進的sp_who3過程可以直接看到進程運行的SQL語句,當然也可自己在sysprocesses中根據進程ID查看
(3)SPID 50以內是SQL Server系統內部用的,進程號大於50的纔是用戶的連接進程
1.4、查看SQL Server數據庫裏的鎖的情況
sp_lock
注:
(1)推薦使用網友改進的sp_who_lock過程檢查死鎖信息,結合了sysprocesses的進程信息和syslockinfo的鎖定信息
1.5、查看 SQL Server、數據庫網關或基礎數據源的特性名和匹配值的列表。
sp_server_info
2、數據庫維護類
2.1、重命名數據庫對象
sp_rename ObjectName,NewObjectName –-數據庫對象
sp_rename [tableName.colName],'NewColName'--字段
2.2、重命名數據庫
exec sp_renamedb 'oldname','newname'
或
alter database dbname modify name='newdbname'
注:
用SQL語句進行數據庫重命名時,需要設置數據庫爲單用戶模式,設置詳見《SQL SERVER 2000 管理——設置數據庫選項》。
2.3、擴展屬性(註釋)
sp_addextendedproperty
--adds a new extended property to a database object
sp_dropextendedproperty
--removes an extended property from a database object
sp_updateextendedproperty
--updates the value of an existing extended property
::fn_listextendedproperty
/*retrieves the value of an extended property or the list of all extended properties from a database object*/
注:
(1)關於註釋這個問題,之前沒用SQL語句去添加過,都是在Enterprise Manager裏面添加的:
查了一下資料,得知SQL Server 2000中引入了擴展屬性,用戶可在各種自定義數據庫對象上定義這些屬性。這些擴展屬性可用於存儲與數據庫對象有關的應用程序或站點特有的信息。
(2)在Oracle中可用COMMENT語句給欄位加註釋,如下:
COMMENT ON COLUMN employees.job_id
IS 'abbreviated job title';
刪除註釋:
COMMENT ON COLUMN employees.job_id IS ' ';
2.4、刷新以優化或防止失效
sp_refreshview
--解決重建視圖的問題,還可以通過重建,發現系統中視圖的語法錯誤。
sp_recompile
--若調整了表結構或索引,使存儲過程和觸發器在下次運行時重新編譯。
2.5、消除孤立用戶
一般登錄被刪除,數據庫用戶會被級聯刪除,只有在登錄被非正常刪除時纔會存在孤立用戶。
sp_change_users_login 'Report'
--列出當前數據庫中未鏈接到任何登錄的用戶
sp_change_users_login 'Auto_Fix','samenamelogin'
--將當前數據庫的 sysusers 表中的用戶條目鏈接到 syslogins 中同名的登錄上。sp_change_users_login 'Update_One', 'user', 'login'
--將當前數據庫中指定的 user 鏈接到 login。login 必須已經存在。
2.6、更改數據所有者(數據庫級所有者)
大家可能會經常碰到一個數據庫備份還原到另外一臺機器結果導致所有的表都不能打開了,原因是建表的時候採用了當時的數據庫用戶。如果想使用當前用戶,則可通過如下方法更改所有者。
--更改當前數據庫的所有者。
exec sp_changedbowner 'newLogin'
--更改表、存儲、試圖對象的所有者,'dbo'處可以使用其他的數據庫賬號,但非系統賬號
exec sp_changeobjectowner 'objectname','newowner'
--批量更改
CREATE PROCEDURE dbo.User_ChangeObjectOwnerBatch
@OldOwner as NVARCHAR(128),
@NewOwner as NVARCHAR(128)
AS
DECLARE @Name as NVARCHAR(128)
DECLARE @Owner as NVARCHAR(128)
DECLARE @OwnerName as NVARCHAR(128)
DECLARE curObject CURSOR FOR
select 'Name' = name,
'Owner' = user_name(uid)
from sysobjects
where user_name(uid)=@OldOwner
order by name
OPEN curObject
FETCH NEXT FROM curObject INTO @Name, @Owner
WHILE(@@FETCH_STATUS=0)
BEGIN
if @Owner=@OldOwner
begin
set @OwnerName = @OldOwner + '.' + rtrim(@Name)
exec sp_changeobjectowner @OwnerName, @NewOwner
end
-- select @name,@NewOwner,@OldOwner
FETCH NEXT FROM curObject INTO @Name, @Owner
END
close curObject
deallocate curObject
3、其他
3.1、動態SQL語句
在T-SQL 應用中,有時我們無法立即確定字段名或表名,我們希望字段名或表名能像變量一樣自由變換,如:
declare @s varchar(255)
select @s = 'username'
select @s from tablename
上述代碼試圖用@s 變量代替字段名userName,但在實際使用中卻會換錯,同樣在表名也無法直接用變量,要解決此問題,我們可以用存儲過程:sp_executesql,如下:示例:
declare @s nvarchar(255)
declare @sql nvarchar(255)
select @s = 'userName'
select @sql = 'select ' + @s + ' from tablename'
exec sp_executesql @sql
exec()可以實現與sp_executesql同樣的功能,只是後者還支持傳參數。如下:
exec sp_executesql N'select * from authors where state=@state and contract=@contract', N'@state char(2), @contract bit', 'CA', 1
注:
(1)在拼完串的時候不要急着exec這個存儲過程,而是應該先select @SQLStatement或print @SQLStatement,以檢查語句正確性;
(2)對於在語句中需要用到的某些符號要利用轉義字符進行轉換,比如'號;
(3)本該存在的空格也要作爲字符來處理,不能少,防止因爲空格而引起語句的不合法;
(4)該過程不支持表變量參數類型;
(5)動態的DDL語法不支持傳參,只能像在exec()中一樣,通過轉化爲字符串類型用+連接;
(5)除了@statement外,參數定義也必須是可以隱式轉換成ntext 的Unicode 常量或變量,所以這裏字符串前面的N 不能省略。
3.2、循環執行
sp_MSForEachDB對服務器上的每個數據庫執行三條命令:
@command1:第一個執行的命令
@replacechar:用另一個佔位賦替換“?”
@command2:第二個執行的命令
@command3:第三個執行的命令
@precommand:進入循環前執行的命令
@postcommand:循環結束後執行的命令
exec sp_MSForEachDB @command1 = 'use ? exec sp_SpaceUsed'
sp_MSForEachTable對數據庫上的每個表執行三條命令:
@command1:第一個執行的命令
@replacechar:用另一個佔位符替換“?”
@command2:第二個執行的命令
@command3:第三個執行的命令
@whereand:Where條件語句 (或 Order By 語句)
@precommand:進入循環前執行的命令
@postcommand:循環結束後執行的命令
exec sp_MSForEachTable
@command1 = "Print '?'",
@command2 = "select count(*) from ?",
@whereand = "ORDER BY 1"
注:
其實,這兩個過程都是用的遊標,完全可以自己實現。
二、擴展存儲過程
注:
(1)不推薦在開發的應用程序中使用未公佈的擴展存儲過程,因爲在以後的SQL SERVER版本中可能會被刪除,如果真的要在數據庫端實現,可以自己封裝COM標準的DLL,建立擴展存儲過程,但是要在能保證兼容性與執行效率的前提下;
(2)即便是公佈了的擴展存儲過程,也要慎用,尤其是要考慮到其安全性。
1、查看信息
1、查看數據庫所在機器操作系統參數
exec master..xp_msver
2、獲得SQL SERVER的版本號
exec master..sp_MSgetversion
3、得到當前SQL SERVER服務器的計算機名稱
execute master..xp_getnetname
4、查看硬盤上的文件、目錄、分區及服務器的驅動器
--參數說明:目錄名,目錄深度,是否顯示文件
execute master..xp_dirtree 'c:'
execute master..xp_dirtree 'c:',1
execute master..xp_dirtree 'c:',1,1
--列出指定目錄的所有下一級子目錄
exec master..xp_subdirs 'C:/'
--查看硬盤分區及可用空間
exec master..xp_fixeddrives
--列出驅動器信息
exec master..xp_availablemedia
name |
low free |
high free |
media type |
C:/ |
2846720 |
1 |
2 |
D:/ |
-156913664 |
0 |
2 |
E:/ |
654663680 |
0 |
2 |
F:/ |
854589440 |
0 |
2 |
G:/ |
0 |
0 |
8 |
H:/ |
0 |
0 |
8 |
|
以字節爲單位的空閒空間 |
|
軟驅(1),硬盤(2),cd-rom(8) |
5、列出服務器上安裝的所有OLEDB提供的程序
exec master..xp_enum_oledb_providers
6、列出服務器上安裝的所有代碼頁
exec master..xp_enumcodepages
7、列出服務器上配置的dsn(odbc數據源名稱)
exec master..xp_enumdsn
8、列出sql server錯誤日誌列表,最後更新時間
exec master..xp_enumerrorlogs
9、列出服務器上所有windows本地組
exec master..xp_enumgroups
10、列出SQL SERVER錯誤日誌的具體內容
exec master..xp_readerrorlog
11、檢測文件存在性
execute master..xp_fileexist 'c:/a.bak'
declare @flag int
exec master..xp_fileexist 'c:/abc.bak',@flag out
if @flag=1
begin
print 'exist'
end else
begin
print 'no exist'
end
2、註冊表
注:
SQL Server中包含了幾個可以訪問註冊表的擴展存儲過程,而且很多人在利用SQL Server進行系統攻擊時,往往都會用到這幾個擴展存儲過程,所以最好在SQL Server中禁用掉它們。
1、讀取指定鍵的值
使用方法:
xp_regread 根鍵,子鍵,鍵值名
實例:
use master
exec xp_regread 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion','CommonFilesDir'
2、寫入指定鍵的值
使用方法:
xp_regwrite 根鍵,子鍵, 值名, 值類型, 值
實例:
use master
exec xp_regwrite 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion','TestValueName','reg_sz','hello'
--注意值類型有兩種:REG_SZ 表示字符型,REG_DWORD 表示整型
3、刪除某個值
使用方法:
xp_regdeletevalue 根鍵,子鍵,值名
實例:
use master
exec xp_regdeletevalue 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion','TestValueName'
4、刪除鍵,包括該鍵下所有值
使用方法:
xp_regdeletekey 根鍵,子鍵
實例:
use master
exec xp_regdeletekey 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion/Testkey'
--如果沒有Testkey這個註冊表項,則會提示:系統找不到指定的文件。
5、寫入多字符串值(即多行的字符串值)
使用方法:
xp_regaddmultistring 根鍵,子鍵,值名,值
--不需要寫值類型,固定爲REG_MULTI_SZ
實例:
use master
exec xp_regaddmultistring 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion','test','hello'
6、刪除多字符串值,但不刪除這個鍵值
使用方法:
xp_regremovemultistring 根鍵,子鍵,值名,值
實例:
use master
exec xp_regremovemultistring 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion','test','hello'
--刪除多字符串值
exec xp_regdeletevalue 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion','test'
--刪除該鍵值
7、以多個記錄集方式返回當前鍵下所有鍵值
使用方法:
xp_regenumvalues 註冊表根鍵,項
實例:
use master
exec xp_regenumvalues 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion/run'
8、以行集方式返回當前鍵下的所有子鍵
使用方法:
xp_regenumkeys 註冊表根鍵,項
實例:
use master
exec xp_regenumkeys 'HKEY_LOCAL_MACHINE',
'software/Microsoft/Windows/CurrentVersion/run'
3、OLE自動化
注:
SQL SERVER存在着非常嚴重的安全隱患。sa的密碼就像Administrator的密碼一樣重要。
假如別人獲得了數據庫超級用戶sa的密碼,那麼就可以在查詢分析器裏使用下面的SQL語句輕易在服務器上創建一個超級用戶:
declare @object int
--創建WScript.Shell
EXEC sp_OACreate 'WScript.Shell',@object OUT
--運行net user iamhacker opendoor /add
--添加一個名字爲iamhacker,密碼爲opendoor的用戶
EXEC sp_OAMethod @object,'Run',NULL,'net user iamhacker opendoor /add'
--把iamhacker添加到Administrators組中
EXEC sp_OAMethod @object,'Run',NULL,'net localgroup Administrators iamhacker /add'
--把iamhacker從User組中刪除
EXEC sp_OAMethod @object,'Run',NULL,'net localgroup Users iamhacker /
其實現方法是SQL SERVER調用COM Automation的強大功能。再配合WSH中的一個對象WScript.Shell的一個方法:Run。
一般SQL SERVER都是配置在SYSTEM的權限下運行的。也就是說,Run所調用的程序也是具有SYSTEM的權限。用Run調用一下NOTEPAD,那麼任務管理器下將有用戶爲SYSTEM的NOTEPA.EXE進程存在。
注:
ActiveX自動腳本的存儲過程如下:
sp_OACreate
sp_OADestroy
sp_OAMethod
sp_OAGetProperty
sp_OASetProperty
sp_OAGetErrorInfo
sp_OAStop
另外還有一個擴展過程xp_cmdshell,也存在同樣的BUG,建議全部刪除。
4、維護擴展存儲過程
1、刪除擴展存儲過程
exec master..sp_dropextendedproc 'xp_cmdshell'
2、新建擴展存儲過程
exec master..sp_addextendedproc 'xp_cmdshell', 'xplog70.dll'
3、查看擴展存儲過程信息
exec master..sp_helpextendedproc 'xp_cmdshell'
xp_cmdshell屏蔽的方法爲:
sp_dropextendedproc 'xp_cmdshell'
如果需要的話,再進行恢復:
sp_addextendedproc 'xp_cmdshell', 'xpsql70.dll'
如果你不知道xp_cmdshell使用的是哪個.dll文件的話:
sp_helpextendedproc 'xp_cmdshell'
所以,將xp_cmdshell屏蔽後,我們還需要做的是將xpsql70.dll文件進行改名,以防止獲得sa的攻擊者將它進行恢復。