日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

基于SQL SERVER觸發(fā)器技術(shù)的實(shí)現(xiàn)

 TUSHUGUANMM 2010-12-19




 

    在數(shù)據(jù)庫(kù)管理系統(tǒng)中,如何保證數(shù)據(jù)庫(kù)中的數(shù)據(jù)完整性是一項(xiàng)重要的課題。數(shù)據(jù)完整性是指存儲(chǔ)在數(shù)據(jù)庫(kù)的數(shù)據(jù)的一致性。主要體現(xiàn)在以下幾個(gè)方面:實(shí)體完整性(Entity Integrity)、域完整性(Domain Integrity)、參照完整性(Referential Integrity)和用戶的自定義完整性(User define Integrity)。目前,已有多種方法來(lái)解決這個(gè)問(wèn)題。從最基本的數(shù)據(jù)類型,到多種形式的約束條件,雖然都提出了數(shù)據(jù)完整性的解決方案,但由于這些方法較為簡(jiǎn)單,不能解決比較復(fù)雜的數(shù)據(jù)完整性問(wèn)題。而觸發(fā)器(Trigger)作為一種高級(jí)的技術(shù),可以輕松地解決任何有關(guān)保證數(shù)據(jù)完整性的問(wèn)題。 
一、在SQL SERVER環(huán)境中使用觸發(fā)器 
   1觸發(fā)器的工作原理 
觸發(fā)器是一種特殊類型的存儲(chǔ)過(guò)程,它與表緊密聯(lián)系在一起,在對(duì)表進(jìn)行插入、刪除和更新時(shí),如該表(也稱觸發(fā)器表)有相應(yīng)操作類型的觸發(fā)器,則觸發(fā)器便會(huì)自動(dòng)觸發(fā)執(zhí)行。觸發(fā)器分為INSERT觸發(fā)器、DELETE觸發(fā)器和UPDATE觸發(fā)器3類。當(dāng)向觸發(fā)器表中插入數(shù)據(jù)時(shí),INSERT觸發(fā)器將觸發(fā)執(zhí)行,新的記錄會(huì)增加到觸發(fā)器表和inseted表中;當(dāng)刪除觸發(fā)器表中的數(shù)據(jù)時(shí),DELETE觸發(fā)器將觸發(fā)執(zhí)行,被刪除的記錄會(huì)存放到deleted表中;當(dāng)更新觸發(fā)器表中的數(shù)據(jù)時(shí),相當(dāng)于插入一條新記錄和刪除一條舊記錄,此時(shí)UPDATE觸發(fā)器將觸發(fā)執(zhí)行,表中原有的記錄存放到deleted表中,修改后的記錄插入到inserted表中。其中inserted表和deleted表是兩個(gè)邏輯表,由系統(tǒng)來(lái)維護(hù),不允許用戶直接對(duì)這兩個(gè)表進(jìn)行修改。它們存放于內(nèi)存中,不存放在數(shù)據(jù)庫(kù)中。這兩個(gè)表的結(jié)構(gòu)總是與被該觸發(fā)器作用的表的結(jié)構(gòu)相同。觸發(fā)器工作完成后,與該觸發(fā)器相關(guān)的這兩個(gè)表也會(huì)被刪除。deleted表用于存儲(chǔ)SQL語(yǔ)言中DELETE和UPDATE語(yǔ)句所影響的行的復(fù)本。在執(zhí)行DELETE或 UPDATE語(yǔ)句時(shí),行從觸發(fā)器表中刪除,并傳輸?shù)?nbsp;deleted 表中。deleted 表和觸發(fā)器表通常沒(méi)有相同的行;inserted 表用于存儲(chǔ) SQL語(yǔ)言中INSERT 和 UPDATE 語(yǔ)句所影響的行的副本。在一個(gè)插入或更新事務(wù)處理中,新建行被同時(shí)添加到 inserted 表和觸發(fā)器表中。inserted 表中的行是觸發(fā)器表中新行的副本。 
  2觸發(fā)器的實(shí)現(xiàn)步驟 
在筆者開發(fā)的教材管理系統(tǒng)中,建立了一個(gè)教材數(shù)據(jù)庫(kù)JCSJK,其中有教材表JCB和教材進(jìn)出明細(xì)表MXB,需要在對(duì)MXB進(jìn)行插入、刪除和修改時(shí),動(dòng)態(tài)地修改JCB中對(duì)應(yīng)教材的庫(kù)存數(shù)量。下面舉例說(shuō)明觸發(fā)器的實(shí)現(xiàn)步驟。為減少篇幅,對(duì)表結(jié)構(gòu)作了簡(jiǎn)化處理。以下操作在Microsoft SQL SERVER環(huán)境中完成。 
  (1)建立教材表JCB,并定義主鍵 
CREATE TABLE [dbo].[JCB] ( 
[教材代碼] [char] (10) NOT NULL , 
[教材名] [char] (30) NOT NULL , 
[價(jià)格] [decimal](18, 2) NOT NULL , 
[庫(kù)存量] [int] NULL , 
[出版社] [char] (20) NULL  
) ON [PRIMARY]ALTER TABLE [dbo].[JCB] WITH NOCHECK ADD 
CONSTRAINT [PK-JCB] PRIMARY KEY CLUSTERED 
([教材代碼] 
) ON [PRIMARY] 
  (2)建立教材進(jìn)出明細(xì)表MXB,并定義主鍵和外?br> CREATE TABLE [dbo].[MXB] ( 
[教材代碼] [char] (10) NOT NULL , 
[日期] [datetime] NOT NULL , 
[教材進(jìn)] [int] NULL , 
[教材出] [int] NULL , 
[備注] [char] (40) NULL  
) ON [PRIMARY] 
ALTER TABLE [dbo].[MXB] WITH NOCHECK ADD 
CONSTRAINT [PK-MXB] PRIMARY KEY CLUSTERED  
([教材代碼], 
[日期] 
) ON [PRIMARY] 
ALTER TABLE [dbo].[MXB] ADD 
CONSTRAINT [FK-MXB-JCB] FOREIGN KEY 
([教材代碼]) REFERENCES [dbo].[JCB] ( 
[教材代碼]) ON DELETE CASCADE ON UPDATE CASCADE 
圖1顯示了JCB和MXB兩個(gè)表的關(guān)系。 
 (3)在MXB上建立INSERT觸發(fā)器 
CREATE TRIGGER MXB-INSE ON [dbo].[MXB] 
FOR INSERT 
ASUPDATE JCB SET 庫(kù)存量=庫(kù)存量+ 
(SELECT 教材進(jìn)-教材出 FROM INSERTED) 
FROM JCB,INSERTEDWHERE JCB.教材代碼=INSERTED.教材代碼 
(4)在MXB上建立DELETE觸發(fā)器 
CREATE TRIGGER MXB-DELE ON [dbo].[MXB] 
FOR DELETE 
AS 
UPDATE JCB SET 庫(kù)存量=庫(kù)存量- 
(SELECT 教材進(jìn)-教材出 FROM DELETED) 
FROM JCB,DELETEDWHERE JCB.教材代碼=DELETED.教材代碼〖HT〗 
  (5)在MXB上建立UPDATE觸發(fā)器 
CREATE TRIGGER MXB-UPDA ON [dbo].[MXB] 
FOR UPDATE 
AS 
BEGINUPDATE JCB SET 庫(kù)存量=庫(kù)存量- 
(SELECT 教材進(jìn)-教材出 FROM DELETED) 
FROM JCB,DELETED 
WHERE JCB.教材代碼=DELETED.教材代碼 
UPDATE JCB SET 庫(kù)存量=庫(kù)存量+ 
(SELECT 教材進(jìn)-教材出 FROM INSERTED) 
FROM JCB,INSERTEDWHERE JCB.教材代碼=INSERTED.教材代碼 
END 
  通過(guò)以上步驟,設(shè)置了MXB表的3類觸發(fā)器,當(dāng)用戶對(duì)MXB表進(jìn)行插入、刪除和修改時(shí),將根據(jù)MXB中教材進(jìn)出的情況動(dòng)態(tài)地修改JCB中對(duì)應(yīng)教材的庫(kù)存量。由于在觸發(fā)器中,涉及到的inserted表和deleted表均存放在內(nèi)存中,因此,觸發(fā)器的執(zhí)行速度較快。 
  3設(shè)計(jì)觸發(fā)器的考慮 
  在寫觸發(fā)器代碼時(shí)需要考慮的一個(gè)重要問(wèn)題就是,引發(fā)觸發(fā)器的語(yǔ)句可以是一個(gè)影響單行的語(yǔ)句,也可以是一個(gè)影響多行的語(yǔ)句。這在 UPDATE 和DELETE 觸發(fā)器中很常見,因?yàn)檫@些語(yǔ)句經(jīng)常作用于多行。而這在 INSERT 觸發(fā)器中就比較少見,因?yàn)榛镜?nbsp;INSERT 語(yǔ)句只添加一行。然而,由于 INSERT 觸發(fā)器可由 INSERT INTO (table_name) SELECT 語(yǔ)句激發(fā),所以,插入許多行可能導(dǎo)致單個(gè)的觸發(fā)器調(diào)用。上面討論的涉及MXB的3類觸發(fā)器都是針對(duì)影響單行的語(yǔ)句。因此,有必要考慮影響多行的語(yǔ)句,這里對(duì)MXB的INSERT觸發(fā)器進(jìn)行討論。 
  (1)可處理多行的MXB上的INSERT觸發(fā)器 
  如果要進(jìn)行多行插入,上面示例中的觸發(fā)器可能就不能正確處理,因?yàn)?nbsp;UPDATE 語(yǔ)句賦值表達(dá)式右邊的表達(dá)式只能是一個(gè)值,而不能是一個(gè)值列表。因此,該觸發(fā)器的作用就是獲取 inserted 表中任意一行的值,并將其添加到JCB表中特定教材代碼值的已有庫(kù)存量值上。如果某個(gè)教材代碼值在inserted 表中出現(xiàn)了多次,則可能無(wú)法得到預(yù)期的結(jié)果。為了正確地更新JCB表,觸發(fā)器就必須適應(yīng)inserted表中出現(xiàn)多行的可能性。這可以通過(guò) SUM 函數(shù)實(shí)現(xiàn),它為 inserted 表中每個(gè)教材代碼計(jì)算教材進(jìn)出的總計(jì)。SUM 函數(shù)存放于相關(guān)子查詢中(SELECT 語(yǔ)句在括號(hào)內(nèi))。該子查詢?yōu)?nbsp;inserted 表中與JCB表的教材代碼匹配或相關(guān)的每個(gè)教材代碼返回一個(gè)單一值。 
CREATE TRIGGER MXB-INSE ON [dbo].[MXB] 
FOR INSERT 
AS 
UPDATE JCB SET 庫(kù)存量=庫(kù)存量+ 
(SELECT SUM(教材進(jìn)-教材出) FROM INSERTED 
WHERE JCB.教材代碼=INSERTED.教材代碼) 
WHERE JCB.教材代碼 IN 
(SELECT 教材代碼 FROM INSERTED) 
  該觸發(fā)器對(duì)單行插入同樣適用,不過(guò),使用該觸發(fā)器時(shí),WHERE 子句中所使用的相關(guān)子查詢和 IN 運(yùn)算符需要額外處理,而這對(duì)于單行插入來(lái)說(shuō)是不必要的。 
  (2)可區(qū)分單行和多行插入的MXB上的INSERT觸發(fā)器可以通過(guò)系統(tǒng)函數(shù)@@ROWCOUNT以區(qū)分單行插入和多行插入,以使觸發(fā)器針對(duì)不同行數(shù)使用最優(yōu)方法。 
CREATE TRIGGER MXB_INSE ON [dbo].[MXB] 
FOR INSERT 
AS 
IF @@ROWCOUNT=1 
BEGIN 
UPDATE JCB SET 庫(kù)存量=庫(kù)存量+ 
(SELECT 教材進(jìn)-教材出 FROM INSERTED) 
FROM JCB,INSERTED 
WHERE JCB.教材代碼=INSERTED.教材代碼 
END 
ELSE 
BEGIN 
UPDATE JCB SET 庫(kù)存量=庫(kù)存量+ 
(SELECT SUM(教材進(jìn)-教材出) FROM INSERTED 
WHERE JCB.教材代碼=INSERTED.教材代碼) 
WHERE JCB.教材代碼 IN 
(SELECT 教材代碼 FROM INSERTED) 
END 
  二、結(jié)論 
  觸發(fā)器應(yīng)用于支持企業(yè)級(jí)商業(yè)解決方案時(shí),是一個(gè)功能十分強(qiáng)大的工具。它可以用于實(shí)現(xiàn)業(yè)務(wù)規(guī)則,可以檢查事務(wù),可以在同一表上創(chuàng)建多個(gè)觸發(fā)器來(lái)分離代碼的功能。另外,通過(guò)使用觸發(fā)器收集的信息,可以提高數(shù)據(jù)庫(kù)的性能,可以用來(lái)維護(hù)那些使用外鍵所不能實(shí)現(xiàn)的復(fù)雜參數(shù)完整性。因此,對(duì)于維護(hù)數(shù)據(jù)表之間一致性,保持?jǐn)?shù)據(jù)的相關(guān)完整性的情況,觸發(fā)器應(yīng)作為首先考慮的技術(shù)。 
儲(chǔ)過(guò)程中返回結(jié)果 
從存儲(chǔ)過(guò)程中返回結(jié)果有三種方式: 
1、 返回結(jié)果集 
這是客戶端應(yīng)用程序返回結(jié)果的最通用的方法。結(jié)果集是通過(guò)使用SELECT語(yǔ)句選擇數(shù)據(jù)產(chǎn)生的。結(jié)果集可以從永久表、臨時(shí)表或局部變量中產(chǎn)生。將結(jié)果返回到另一個(gè)存儲(chǔ)過(guò)程不是一種有效的方法。存儲(chǔ)過(guò)程不能訪問(wèn)另一個(gè)存儲(chǔ)過(guò)程建立的結(jié)果集。 
例如從永久表中返回結(jié)果集: 
USE pubs 
GO 
CREATE PROCEDURE ap_CreateResultFromPermtable 
AS 
SELECT au_iname FROM authors 
GO 
例如從局部變量中創(chuàng)建結(jié)果集: 
USE pubs 
GO 
CREATE PROCEDURE ap_CreateResultFromVariable 
AS 
DECLARE @au_iname char(20) 
SELECT @au_iname = au_iname FROM authors 
WHERE au_id = ‘172-32-1176’ 
SELECT @au_id 
GO 
2、 設(shè)置OUTPUT參數(shù)的值 
輸出參數(shù)經(jīng)常用來(lái)從存儲(chǔ)過(guò)程中檢索出結(jié)果。如果某個(gè)參數(shù)在傳輸?shù)酱鎯?chǔ)過(guò)程中時(shí)被定義成OUTPUT,則對(duì)該參數(shù)的任何修改在退出存儲(chǔ)之后仍然有效。 
例如: 
USE pubs 
GO 
CREATE PROCEDURE ap_SetOutputVar @count integer OUTPUT 
AS 
SELECT @count = count(*) FROM authors 
GO 
從輸出參數(shù)中檢索出值: 
USE pubs 
GO 
CREATE PROCEDURE ap_GetOutputVar 
AS 
DECLARE @num integer 
EXECUTE ap_SetOutputVar @num OUTPUT 
PRINT “the count is”+convert(char,@num) 
GO 
? 將游標(biāo)使用成OUTPUT參數(shù)。游標(biāo)可以使用OUTPUT(輸出)參數(shù),但不能使用成輸入?yún)?shù)。也就是說(shuō),游標(biāo)可以作為結(jié)果返回,但卻不能傳輸?shù)竭^(guò)程中去。當(dāng)游標(biāo)被用作參數(shù)時(shí),需要限定其為OUTPUT和VARYING。VARYING關(guān)鍵字指出該結(jié)果集要用來(lái)支持輸出參數(shù)。這樣就提供了將結(jié)果集返回到調(diào)用過(guò)程的能力。 
例如: 
USE pubs 
GO 
CREATE PROCEDURE GetTitleCount @count_cursor CURSOR VARYING OUTPUT 
AS 
SET @count_cursor = CURSOR 
FOR 
SELECT au_id,count(*) 
FROM titleauthors 
GROUP BY au_id 
OPEN @count_cursor 
GO 
3、 通過(guò)RETURN參數(shù)返回狀態(tài) 
這是一種從存儲(chǔ)過(guò)程返回錯(cuò)誤碼的方法。存儲(chǔ)過(guò)程總是返回一個(gè)狀態(tài)值,用戶也可以使用RETURN語(yǔ)句返回自己的狀態(tài)。 
例如: 
USE pubs 
GO 
CREATE PROCEDURE ap_SetReturnStatus 
AS 
DECLARE @count integer 
SELECT @count = count(*) FROM authors 
IF @count = 0 
RETURN(1) 
ELSE 
RETURN (0) 
GO 
例如檢索出返回的狀態(tài): 
USE pubs 
GO 
CREATE PROCEDURE ap_GetReturnStatus 
AS 
DECLARE @status integer 
EXECUTE @status = ap_SetReturnStatus 
IF @status = 1 
PRINT “No rows found” 
ELSE 
PRINT “successful” 
GO 
在存儲(chǔ)過(guò)程中進(jìn)行錯(cuò)誤處理 
如同其它程序一樣,在存儲(chǔ)過(guò)程中進(jìn)行錯(cuò)誤處理是非常重要的。系統(tǒng)變更@@error在執(zhí)行每一個(gè)Transact SQL語(yǔ)句之后都會(huì)得到一個(gè)值。對(duì)于成功的執(zhí)行,@@error的值為0,如果出現(xiàn)錯(cuò)誤,則@@error中將包含錯(cuò)誤信息。@@error系統(tǒng)變量對(duì)存儲(chǔ)過(guò)程的錯(cuò)誤處理是非常重要的。 
注意:為了防止錯(cuò)誤,@@error所能設(shè)置的值在sysmessages表的“error”中反映了出來(lái)。 
在存儲(chǔ)過(guò)程中的錯(cuò)誤有兩種類型: 
1、 數(shù)據(jù)庫(kù)相關(guān)的錯(cuò)誤 
這些錯(cuò)誤是由數(shù)據(jù)庫(kù)的不一致性引起的,系統(tǒng)使用非0的@@error值表示特定的數(shù)據(jù)庫(kù)問(wèn)題。在Transact SQL執(zhí)行之后,可以通過(guò)@@error獲得所出現(xiàn)的錯(cuò)誤。如果發(fā)現(xiàn)@@error不為0,則必須采取必要的行動(dòng),大多數(shù)情況下,存儲(chǔ)將不再繼續(xù)進(jìn)行處理而返回。下面的示例展示了典型的獲取數(shù)據(jù)庫(kù)錯(cuò)誤的方法。該過(guò)程將錯(cuò)誤代碼放置到輸出變量中,這樣,調(diào)用程序就能夠訪問(wèn)到。 
USE pubs 
GO 
CREATE PROCEDURE ap_TrapDatabaseError @return_code integer OUTPUT 
AS 
UPDATE authors SET au_iname = “Jackson” 
WHERE au_iname = “Smith” 
IF @@error <> 0 
BEGIN 
SELECT @return_code = @@error 
RETURN 
END 
ELSE 
@return_code = 0 
GO 
2、 業(yè)務(wù)邏輯錯(cuò)誤 
這些錯(cuò)誤是由于違反了業(yè)務(wù)規(guī)則而引起的。要獲取這些錯(cuò)誤,首先需要定義業(yè)務(wù)規(guī)則,基于這些規(guī)則,需要在存儲(chǔ)過(guò)程中增加必要的錯(cuò)誤檢測(cè)代碼。人們經(jīng)常使用RAISERROR語(yǔ)句通報(bào)這些錯(cuò)誤。RAISERROR提供了返回用戶定義錯(cuò)誤及將@@error變量設(shè)置成用戶定義錯(cuò)誤號(hào)的能力。錯(cuò)誤消息可以被動(dòng)態(tài)地建立,或者基于錯(cuò)誤號(hào)從“sysmessages”表中檢索到。一旦出現(xiàn)了錯(cuò)誤,錯(cuò)誤就會(huì)以一種服務(wù)器錯(cuò)誤消息的方式返回到客戶機(jī)。下面是RAISERROR命令的語(yǔ)法: 
RAISERROR (msg_id | msg_str, severity, state 
[, argument ][,…n])) 
[WITH options] 
Msg_id指明用戶定義消息的id,該消息存儲(chǔ)在“sysmessages”系統(tǒng)表中。 
Msg_str用于動(dòng)態(tài)創(chuàng)建消息的消息字符串。這與C語(yǔ)言中的“printf”非常相似。 
Severity定義用戶賦值的錯(cuò)誤消息嚴(yán)重程度。 
State是從1到127的任意整數(shù)值,它表示錯(cuò)誤的調(diào)用狀態(tài)信息。負(fù)數(shù)的state值將缺省為1。 
OPTIONS指明錯(cuò)誤的定制選項(xiàng)。OPTIONS的有效值如下: 
1) LOG。 
將錯(cuò)誤記錄到服務(wù)器錯(cuò)誤日志和NT事件日志中。該選項(xiàng)需要消息帶有從19到25的嚴(yán)重程度。而只有系統(tǒng)管理員才能發(fā)出這種消息。 
2) NOWAIT。 
將消息立即發(fā)送到客戶端服務(wù)器。 
3) SETERROR。 
不管其嚴(yán)重級(jí)別如何,將@@error的值設(shè)置為msg_id或5000。 
遠(yuǎn)程過(guò)程調(diào)用 
SQL Server提供了調(diào)用駐留在不同服務(wù)器上的存儲(chǔ)過(guò)程的能力。調(diào)用這樣的存儲(chǔ)過(guò)程稱謂遠(yuǎn)程存儲(chǔ)過(guò)程調(diào)用。為了使得調(diào)用能從一個(gè)SQL Server轉(zhuǎn)移到另一個(gè)服務(wù)器,兩個(gè)服務(wù)器應(yīng)該相互定義成對(duì)方的有效遠(yuǎn)程服務(wù)器。 
設(shè)置遠(yuǎn)程服務(wù)器的配置: 
? 擴(kuò)展某個(gè)服務(wù)器的組。 
? 右擊該服務(wù)器并點(diǎn)擊“Properties”。 
? 設(shè)置選項(xiàng)“Allow other SQL Servers to connect remotely to this SQL server via RPC”。 
? 設(shè)置“Query time out”選項(xiàng)的值,該值指定從一個(gè)查詢處理返回所能等待的秒數(shù)。缺省值為0,表示允許無(wú)限的等待時(shí)間。 
? 設(shè)置完成配置選項(xiàng)之后,點(diǎn)擊“OK”。 
? 重新啟動(dòng)服務(wù)器之后,修改將會(huì)生效。 
? 在另一臺(tái)遠(yuǎn)程服務(wù)器上重復(fù)相同的步驟。 
調(diào)用遠(yuǎn)程存儲(chǔ)過(guò)程需要指明服務(wù)器的名稱,后帶數(shù)據(jù)庫(kù)的名稱和擁有者的名稱。下面是在不同的服務(wù)器(Server2)上調(diào)用一個(gè)存儲(chǔ)過(guò)程的示例。 
Exec server2.pubs.dbo.myproc 
豆豆的后話: 
這里只是粗淺的介紹了SQL Server常用的知識(shí),對(duì)象也是基于SQL Server數(shù)據(jù)庫(kù)編寫應(yīng)用程序的編程人員,而非數(shù)據(jù)庫(kù)管理者。但對(duì)于應(yīng)用程序編程者,了解數(shù)據(jù)庫(kù)的管理也是非常有用的。建議在以后的時(shí)間自行去了解數(shù)據(jù)庫(kù)的管理,這對(duì)于優(yōu)化程序也是相當(dāng)有用的。 
 
查看鎖信息 
create table #t(req_spid int,obj_name sysname) 
declare @s nvarchar(4000) 
,@rid int,@dbname sysname,@id int,@objname sysname 
declare tb cursor for 
select distinct req_spid,dbname=db_name(rsc_dbid),rsc_objid 
from master..syslockinfo where rsc_type in(4,5) 
open tb 
fetch next from tb into @rid,@dbname,@id 
while @@fetch_status=0 
begin 
set @objname=name from ['+@dbname+']..sysobjects where id=@id' 
exec sp_executesql @s,N'@objname sysname out,@id int',@objname out,@id 
insert into #t values(@rid,@objname) 
fetch next from tb into @rid,@dbname,@id 
end 
close tb 
deallocate tb 
select 進(jìn)程id=a.req_spid 
,數(shù)據(jù)庫(kù)=db_name(rsc_dbid) 
,類型=case rsc_type when 1 then 'NULL 資源(未使用)' when 2 then '數(shù)據(jù)庫(kù)' 
when 3 then '文件' 
when 4 then '索引' 
when 5 then '表' 
when 6 then '頁(yè)' 
when 7 then '鍵' 
when 8 then '擴(kuò)展盤區(qū)' 
when 9 then 'RID(行 ID)' 
when 10 then '應(yīng)用程序' 
end 
,對(duì)象id=rsc_objid 
,對(duì)象名=b.obj_name 
,rsc_indid 
from master..syslockinfo a left join #t b on a.req_spid=b.req_spid 
go 
drop table #t 
 

Transact-SQL 參考 
sysobject
在數(shù)據(jù)庫(kù)內(nèi)創(chuàng)建的每個(gè)對(duì)象(約束、默認(rèn)值、日志、規(guī)則、存儲(chǔ)過(guò)程等)在表中占一行。只有在 tempdb 內(nèi),每個(gè)臨時(shí)對(duì)象才在該表中占一行。 
列名 數(shù)據(jù)類型 描述 
name sysname 對(duì)象名。 
Id int 對(duì)象標(biāo)識(shí)號(hào)。 
xtype char(2) 對(duì)象類型??梢允窍铝袑?duì)象類型中的一種: C = CHECK 約束 
D = 默認(rèn)值或 DEFAULT 約束 F = FOREIGN KEY 約束 
L = 日志 
FN = 標(biāo)量函數(shù) 
IF = 內(nèi)嵌表函數(shù) 
P = 存儲(chǔ)過(guò)程 
PK = PRIMARY KEY 約束(類型是 K) 
RF = 復(fù)制篩選存儲(chǔ)過(guò)程 
S = 系統(tǒng)表 
TF = 表函數(shù) 
TR = 觸發(fā)器 
U = 用戶表 
UQ = UNIQUE 約束(類型是 K) 
V = 視圖 
X = 擴(kuò)展存儲(chǔ)過(guò)程 

uid smallint 所有者對(duì)象的用戶 ID。 
info smallint 保留。僅限內(nèi)部使用。 
status int 保留。僅限內(nèi)部使用。 
base_schema_ 
ver int 保留。僅限內(nèi)部使用。 
replinfo int 保留。供復(fù)制使用。 
parent_obj int 父對(duì)象的對(duì)象標(biāo)識(shí)號(hào)(例如,對(duì)于觸發(fā)器或約束,該標(biāo)識(shí)號(hào)為表 ID)。 
crdate datetime 對(duì)象的創(chuàng)建日期。 
ftcatid smallint 為全文索引注冊(cè)的所有用戶表的全文目錄標(biāo)識(shí)符,對(duì)于沒(méi)有注冊(cè)的所有用戶表則為 0。 
schema_ver int 版本號(hào),該版本號(hào)在每次表的架構(gòu)更改時(shí)都增加。 
stats_schema_ 
ver int 保留。僅限內(nèi)部使用。 
type char(2) 對(duì)象類型。可以是下列值之一: 
C = CHECK 約束 
D = 默認(rèn)值或 DEFAULT 約束 
F = FOREIGN KEY 約束 
FN = 標(biāo)量函數(shù) 
IF = 內(nèi)嵌表函數(shù) 
K = PRIMARY KEY 或 UNIQUE 約束 
L = 日志 
P = 存儲(chǔ)過(guò)程 
R = 規(guī)則 
RF = 復(fù)制篩選存儲(chǔ)過(guò)程 
S = 系統(tǒng)表 
TF = 表函數(shù) 
TR = 觸發(fā)器 
U = 用戶表 
V = 視圖 
X = 擴(kuò)展存儲(chǔ)過(guò)程 

userstat smallint 保留。 
sysstat smallint 內(nèi)部狀態(tài)信息。 
indexdel smallint 保留。 
refdate datetime 留作以后使用。 
version int 留作以后使用。 
deltrig int 保留。 
instrig int 保留。 
updtrig int 保留。 
seltrig int 保留。 
category int 用于發(fā)布、約束和標(biāo)識(shí)。 
cache smallint 保留。 
查詢指定表在那些數(shù)據(jù)庫(kù)中存在 
declare @tbname sysname set 客戶資料' declare @dbname sysname,@sql nvarchar(4000),@re bit,@sql1 varchar(8000) set @sql1='' 
declare tb cursor for select name from master..sysdatabases 
open tb 
fetch next from tb into @dbname 
while @@fetch_status=0 
begin 
set @re=case when exists(select 1 from [' 
+@dbname+']..sysobjects where xtype=''U'' and name=''' 
+@tbname+''') then 1 else 0 end' 
exec sp_executesql @sql,N'@re bit out',@re out 
if @re=1 set @sql1=@sql1+' union all select '''+@dbname+'''' 
fetch next from tb into @dbname 
end 
close tb 
deallocate tb 
set @sql1=substring(@sql1,12,8000) 
exec(@sql1)   

比較兩個(gè)數(shù)據(jù)庫(kù)的表結(jié)構(gòu)差異 
exec p_comparestructure 'xzkh_model','xzkh_new' 
--*/ if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_comparestructure]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) 
drop procedure [dbo].[p_comparestructure] 
GO 
create proc p_comparestructure 
@dbname1 varchar(250), --要比較的數(shù)據(jù)庫(kù)名1 
@dbname2 varchar(250) --要比較的數(shù)據(jù)庫(kù)名2 
as 
create table #tb1(表名1 varchar(250),字段名 varchar(250),序號(hào) int,標(biāo)識(shí) bit,主鍵 bit,類型 varchar(250), 
占用字節(jié)數(shù) int,長(zhǎng)度 int,小數(shù)位數(shù) int,允許空 bit,默認(rèn)值 varchar(500),字段說(shuō)明 varchar(500)) 
create table #tb2(表名2 varchar(250),字段名 varchar(250),序號(hào) int,標(biāo)識(shí) bit,主鍵 bit,類型 varchar(250), 占用字節(jié)數(shù) int,長(zhǎng)度 int,小數(shù)位數(shù) int,允許空 bit,默認(rèn)值 varchar(500),字段說(shuō)明 varchar(500)) --得到數(shù)據(jù)庫(kù)1的結(jié)構(gòu) 
exec('insert into #tb1 SELECT 表名=d.name,字段名=a.name,序號(hào)=a.colid, 
標(biāo)識(shí)=case when a.status=0x80 then 1 else 0 end, 主鍵=case when exists(SELECT 1 FROM '+@dbname1+'..sysobjects where xtype=''PK'' and name in (SELECT name FROM '+@dbname1+'..sysindexes WHERE indid in(SELECT indid FROM '+@dbname1+'..sysindexkeys WHERE id = a.id AND colid=a.colid ))) then 1 else 0 end, 
類型=b.name, 占用字節(jié)數(shù)=a.length,長(zhǎng)度=a.prec,小數(shù)位數(shù)=a.scale, 允許空=a.isnullable, 
默認(rèn)值=isnull(e.text,''''''),字段說(shuō)明=isnull(g.[value],'''''') FROM '+@dbname1+'..syscolumns a left join '+@dbname1+'..systypes b on a.xtype=b.xusertype inner join '+@dbname1+'..sysobjects d on a.id=d.id and d.xtype=''U'' and d.name<>''dtproperties'' left join '+@dbname1+'..syscomments e on a.cdefault=e.id left join '+@dbname1+'..sysproperties g on a.id=g.id and a.colid=g.smallid 
order by a.id,a.colorder') --得到數(shù)據(jù)庫(kù)2的結(jié)構(gòu) 
exec('insert into #tb2 SELECT表名=d.name,字段名=a.name,序號(hào)=a.colid, 
標(biāo)識(shí)=case when a.status=0x80 then 1 else 0 end, 主鍵=case when exists(SELECT 1 FROM '+@dbname2+'..sysobjects where xtype=''PK'' and name in (SELECT name FROM '+@dbname2+'..sysindexes WHERE indid in(SELECT indid FROM '+@dbname2+'..sysindexkeys WHERE id = a.id AND colid=a.colid ))) then 1 else 0 end, 
類型=b.name, 占用字節(jié)數(shù)=a.length,長(zhǎng)度=a.prec,小數(shù)位數(shù)=a.scale, 允許空=a.isnullable, 
默認(rèn)值=isnull(e.text,''''''),字段說(shuō)明=isnull(g.[value],'''''') 
FROM '+@dbname2+'..syscolumns a left join '+@dbname2+'..systypes b on a.xtype=b.xusertype 
inner join '+@dbname2+'..sysobjects d on a.id=d.id and d.xtype=''U'' and d.name<>''dtproperties'' 
left join '+@dbname2+'..syscomments e on a.cdefault=e.id left join '+@dbname2+'..sysproperties g on a.id=g.id and a.colid=g.smallid order by a.id,a.colorder') 
--and not exists(select 1 from #tb2 where 表名2=a.表名1) 
select 比較結(jié)果=case when a.表名1 is null and b.序號(hào)=1 then '庫(kù)1缺少表:'+b.表名2 
when b.表名2 is null and a.序號(hào)=1 then '庫(kù)2缺少表:'+a.表名1 when a.字段名 is null and exists(select 1 from #tb1 where 表名1=b.表名2) then '庫(kù)1 ['+b.表名2+'] 缺少字 段:'+b.字段名when b.字段名 is null and exists(select 1 from #tb2 where 表名2=a.表名1) then '庫(kù)2 ['+a.表名1+'] 缺少字段:'+a.字段名 when a.標(biāo)識(shí)<>b.標(biāo)識(shí) then '標(biāo)識(shí)不同' when a.主鍵<>b.主鍵 then '主鍵設(shè)置不同' when a.類型<>b.類型 then '字段類型不同' when a.占用字節(jié)數(shù)<>b.占用字節(jié)數(shù) then '占用字節(jié)數(shù)' when a.長(zhǎng)度<>b.長(zhǎng)度 then '長(zhǎng)度不同' when a.小數(shù)位數(shù)<>b.小數(shù)位數(shù) then '小數(shù)位數(shù)不同' when a.允許空<>b.允許空 then '是否允許空不同' 
when a.默認(rèn)值<>b.默認(rèn)值 then '默認(rèn)值不同' when a.字段說(shuō)明<>b.字段說(shuō)明 then '字段說(shuō)明不同' else '' end, * from #tb1 a full join #tb2 b on a.表名1=b.表名2 and a.字段名=b.字段名 
where a.表名1 is null or a.字段名 is null or b.表名2 is null or b.字段名 is null or a.標(biāo)識(shí)<>b.標(biāo)識(shí) or a.主鍵<>b.主鍵 or a.類型<>b.類型 or a.占用字節(jié)數(shù)<>b.占用字節(jié)數(shù) or a.長(zhǎng)度<>b.長(zhǎng)度 or a.小數(shù)位數(shù)<>b.小數(shù)位數(shù) or a.允許空<>b.允許空 or a.默認(rèn)值<>b.默認(rèn)值 or a.字段說(shuō)明<>b.字段說(shuō)明 order by isnull(a.表名1,b.表名2),isnull(a.序號(hào),b.序號(hào))--isnull(a.字段名,b.字段名) go 
sql 系統(tǒng)存儲(chǔ)過(guò)程xp_cmdshell使用 
xp_cmdshell 
以操作系統(tǒng)命令行解釋器的方式執(zhí)行給定的命令字符串,并以文本行方式返回任何輸出。授予非管理用戶執(zhí)行 xp_cmdshell 的權(quán)限。 
說(shuō)明 在 Microsoft? Windows? 95 或 Microsoft Windows 98 操作系統(tǒng)中執(zhí)行 xp_cmdshell 時(shí),將不把 xp_cmdshell 的返回代碼設(shè)置為喚醒調(diào)用的可執(zhí)行文件的進(jìn)程退出代碼。返回代碼始終為 0。 
語(yǔ)法 
xp_cmdshell {'command_string'} [, no_output] 
參數(shù) 
'command_string' 
是在操作系統(tǒng)命令行解釋器上執(zhí)行的命令字符串。command_string 的數(shù)據(jù)類型為 varchar(255) 或 nvarchar(4000),沒(méi)有默認(rèn)值。command_string 不能包含一對(duì)以上的雙引號(hào)。如果由 command_string 引用的文件路徑或程序名稱中有空格,則需要使用一對(duì)引號(hào)。如果使用嵌入空格不方便,可考慮使用 FAT 8.3 文件名作為解決辦法。 
no_output 
是可選參數(shù),表示執(zhí)行給定的 command_string,但不向客戶端返回任何輸出。 
返回代碼值 
0(成功)或 1(失敗) 
結(jié)果集 
執(zhí)行下列 xp_cmdshell 語(yǔ)句將返回當(dāng)前目錄的目錄列表。 
xp_cmdshell 'dir *.exe' 
行以 nvarchar(255) 列的形式返回。 
執(zhí)行下列 xp_cmdshell 語(yǔ)句將返回隨后的結(jié)果集: 
xp_cmdshell 'dir *.exe', NO_OUTPUT 
下面是結(jié)果: 
The command(s) completed successfully. 
注釋 
xp_cmdshell 以同步方式操作。在命令行解釋器命令執(zhí)行完畢之前,不會(huì)返回控制。 
當(dāng)授予用戶執(zhí)行權(quán)限時(shí),用戶能在 Microsoft Windows NT? 命令行解釋器上執(zhí)行運(yùn)行 Microsoft SQL Server? 的帳戶有權(quán)執(zhí)行的任何操作系統(tǒng)命令。 
默認(rèn)情況下,只有 sysadmin 固定服務(wù)器角色的成員才能執(zhí)行此擴(kuò)展存儲(chǔ)過(guò)程。但是,也可以授予其他用戶執(zhí)行此存儲(chǔ)過(guò)程的權(quán)限。 
當(dāng)作為 sysadmin 固定服務(wù)器角色成員的用戶喚醒調(diào)用 xp_cmdshell 時(shí),將在運(yùn)行 SQL Server 服務(wù)的安全上下文中執(zhí)行 xp_cmdshell。當(dāng)用戶不是 sysadmin 組的成員時(shí),xp_cmdshell 將模擬使用 xp_sqlagent_proxy_account 指定的 SQL Server 代理程序的代理帳戶。如果代理帳戶不能用,則 xp_cmdshell 將失敗。這只是針對(duì)于 Microsoft? Windows NT? 4.0 和 Windows 2000。在 Windows 9.x 上,沒(méi)有模擬,且 xp_cmdshell 始終在啟動(dòng) SQL Server 的 Windows 9.x 用戶的安全上下文下執(zhí)行。 
說(shuō)明 在早期版本中,獲得 xp_cmdshell 執(zhí)行權(quán)限的用戶在 MSSQLServer 服務(wù)的用戶帳戶上下文中運(yùn)行命令??梢酝ㄟ^(guò)配置選項(xiàng)配置 SQL Server,以便對(duì) SQL Server 無(wú) sa 訪問(wèn)權(quán)限的用戶能夠在 SQLExecutiveCmdExec Windows NT 帳戶的上下文中運(yùn)行 xp_cmdshell。在 SQL Server 7.0 中,該帳戶稱為 SQLAgentCmdExec。現(xiàn)在,不是 sysadmin 固定服務(wù)器角色成員的用戶將在該帳戶上下文中運(yùn)行命令,而無(wú)需再進(jìn)行配置更改。 
權(quán)限 
xp_deletemail 的執(zhí)行權(quán)限默認(rèn)授予 sysadmin 固定服務(wù)器角色的成員,但可以授予其他用戶。 
重要 如果為 MSSQLServer 服務(wù)選用的 Windows NT 帳戶不是本地管理員組的成員,則非 sysadmin 固定服務(wù)器角色成員的用戶將無(wú)法執(zhí)行 xp_cmdshell。 
示例 
A. 返回可執(zhí)行文件列表 
下例顯示執(zhí)行目錄命令的 xp_cmdshell 擴(kuò)展存儲(chǔ)過(guò)程。 
EXEC master..xp_cmdshell 'dir *.exe' 
B. 使用 Windows NT net 命令 
下例顯示 xp_cmdshell 在存儲(chǔ)過(guò)程中的使用。下例先用 net send 通知用戶 SQL Server 即將關(guān)閉,然后用 net pause 暫停服務(wù)器,最后用 net stop 關(guān)閉服務(wù)器。 
CREATE PROC shutdown10 
AS 
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down 
in 10 minutes. No more connections allowed.', no_output 
EXEC xp_cmdshell 'net pause sqlserver' 
WAITFOR DELAY '00:05:00' 
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server shutting down 
in 5 minutes.', no_output 
WAITFOR DELAY '00:04:00' 
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down 
in 1 minute. Log off now.', no_output 
WAITFOR DELAY '00:01:00' 
EXEC xp_cmdshell 'net stop sqlserver', no_output 
C. 不返回輸出 
下例使用 xp_cmdshell 執(zhí)行命令字符串,且不向客戶端返回輸出。 
USE master 
EXEC xp_cmdshell 'copy c:\sqldumps\pubs.dmp \\server2\backups\sqldumps', 
NO_OUTPUT 
D. 使用返回狀態(tài) 
在下例中,xp_cmdshell 擴(kuò)展存儲(chǔ)過(guò)程也給出了返回狀態(tài)。返回代碼值存儲(chǔ)在變量 @result 中。 
DECLARE @result int 
EXEC @result = xp_cmdshell 'dir *.exe' 
IF (@result = 0) 
PRINT 'Success' 
ELSE 
PRINT 'Failure' 
E. 將變量?jī)?nèi)容寫入文件 
下例將當(dāng)前目錄內(nèi)容寫入當(dāng)前服務(wù)器目錄下名為 dir_out.txt 的文件中。 
DECLARE @cmd sysname, @var sysname 
SET @var = 'dir /p' 
SET @cmd = 'echo ' + @var + ' > dir_out.txt' 
EXEC master..xp_cmdshell @cmd 
SQL 2K 安全指南 
數(shù)據(jù)庫(kù)是電子商務(wù)、金融以及ERP系統(tǒng)的基礎(chǔ),通常都保存著重要的商業(yè)伙伴和客戶信息。大多數(shù)企業(yè)、組織以及政府部門的電子數(shù)據(jù)都保存在各種數(shù)據(jù)庫(kù)中,他們用這些數(shù)據(jù)庫(kù)保存一些個(gè)人資料,比如員工薪水、個(gè)人資料等等。數(shù)據(jù)庫(kù)服務(wù)器還掌握著敏感的金融數(shù)據(jù)。包括交易記錄、商業(yè)事務(wù)和賬號(hào)數(shù)據(jù),戰(zhàn)略上的或者專業(yè)的信息,比如專利和工程數(shù)據(jù),甚至市場(chǎng)計(jì)劃等等應(yīng)該保護(hù)起來(lái)防止競(jìng)爭(zhēng)者和其他非法者獲取的資料。數(shù)據(jù)完整性和合法存取會(huì)受到很多方面的安全威脅,包括密碼策略、系統(tǒng)后門、數(shù)據(jù)庫(kù)操作以及本身的安全方案。但是數(shù)據(jù)庫(kù)通常沒(méi)有象操作系統(tǒng)和網(wǎng)絡(luò)這樣在安全性上受到重視。 
微軟的SQL Server是一種廣泛使用的數(shù)據(jù)庫(kù),很多電子商務(wù)網(wǎng)站、企業(yè)內(nèi)部信息化平臺(tái)等都是基于SQL Server上的,但是數(shù)據(jù)庫(kù)的安全性還沒(méi)有被人們更系統(tǒng)的安全性等同起來(lái),多數(shù)管理員認(rèn)為只要把網(wǎng)絡(luò)和 
操作系統(tǒng)的安全搞好了,那么所有的應(yīng)用程序也就安全了。大多數(shù)系統(tǒng)管理員對(duì)數(shù)據(jù)庫(kù)不熟悉而數(shù)據(jù)庫(kù)管理員有對(duì)安全問(wèn)題關(guān)心太少,而且一些安全公司也忽略數(shù)據(jù)庫(kù)安全,這就使數(shù)據(jù)庫(kù)的安全問(wèn)題更加嚴(yán)峻了。數(shù)據(jù)庫(kù)系統(tǒng)中存在的安全漏洞和不當(dāng)?shù)呐渲猛ǔ?huì)造成嚴(yán)重的后果,而且都難以發(fā)現(xiàn)。數(shù)據(jù)庫(kù)應(yīng)用程序通常同操作系統(tǒng)的最高管理員密切相關(guān)。廣泛SQL Server數(shù)據(jù)庫(kù)又是屬于“端口”型的數(shù)據(jù)庫(kù),這就表示任何人都能夠用分析工具試圖連接到數(shù)據(jù)庫(kù)上,從而繞過(guò)操作系統(tǒng)的安全機(jī)制,進(jìn)而闖入系統(tǒng)、破壞和竊取數(shù)據(jù)資料,甚至破壞整個(gè)系統(tǒng)。 
這里,我們主要談?wù)撚嘘P(guān)SQL Server2000數(shù)據(jù)庫(kù)的安全配置以及一些相關(guān)的安全和使用上的問(wèn)題。 
在進(jìn)行SQL Server 2000數(shù)據(jù)庫(kù)的安全配置之前,首先你必須對(duì)操作系統(tǒng)進(jìn)行安全配置,保證你的操作系統(tǒng)處于安全狀態(tài)。然后對(duì)你要使用的操作數(shù)據(jù)庫(kù)軟件(程序)進(jìn)行必要的安全審核,比如對(duì)ASP、PHP等腳本,這是很多基于數(shù)據(jù)庫(kù)的WEB應(yīng)用常出現(xiàn)的安全隱患,對(duì)于腳本主要是一個(gè)過(guò)濾問(wèn)題,需要過(guò)濾一些類似 , ‘ ; @ / 等字符,防止破壞者構(gòu)造惡意的SQL語(yǔ)句。接著,安裝SQL Server2000后請(qǐng)打上補(bǔ)丁sp1以及最新的sp2。 
下載地址是:http://www.microsoft.com/sql/downlo...ds/2000/sp2.asp 
在做完上面三步基礎(chǔ)之后,我們?cè)賮?lái)討論SQL Server的安全配置。
1、使用安全的密碼策略 
我們把密碼策略擺在所有安全配置的第一步,請(qǐng)注意,很多數(shù)據(jù)庫(kù)賬號(hào)的密碼過(guò)于簡(jiǎn)單,這跟系統(tǒng)密碼過(guò)于簡(jiǎn)單是一個(gè)道理。對(duì)于sa更應(yīng)該注意,同時(shí)不要讓sa賬號(hào)的密碼寫于應(yīng)用程序或者腳本中。健壯的密碼是安全的第一步! 
SQL Server2000安裝的時(shí)候,如果是使用混合模式,那么就需要輸入sa的密碼,除非你確認(rèn)必須使用空密碼。這比以前的版本有所改進(jìn)。 
同時(shí)養(yǎng)成定期修改密碼的好習(xí)慣。數(shù)據(jù)庫(kù)管理員應(yīng)該定期查看是否有不符合密碼要求的賬號(hào)。比如使用下面的SQL語(yǔ)句: 
Use master 
Select name,Password from syslogins where password is null 
2、使用安全的賬號(hào)策略。 
由于SQL Server不能更改sa用戶名稱,也不能刪除這個(gè)超級(jí)用戶,所以,我們必須對(duì)這個(gè)賬號(hào)進(jìn)行最強(qiáng)的保護(hù),當(dāng)然,包括使用一個(gè)非常強(qiáng)壯的密碼,最好不要在數(shù)據(jù)庫(kù)應(yīng)用中使用sa賬號(hào),只有當(dāng)沒(méi)有其它方法登錄到 SQL Server 實(shí)例(例如,當(dāng)其它系統(tǒng)管理員不可用或忘記了密碼)時(shí)才使用 sa。建議數(shù)據(jù)庫(kù)管理員新建立一個(gè)擁有與sa一樣權(quán)限的超級(jí)用戶來(lái)管理數(shù)據(jù)庫(kù)。安全的賬號(hào)策略還包括不要讓管理員權(quán)限的賬號(hào)泛濫。 
SQL Server的認(rèn)證模式有Windows身份認(rèn)證和混合身份認(rèn)證兩種。如果數(shù)據(jù)庫(kù)管理員不希望操作系統(tǒng)管理員來(lái)通過(guò)操作系統(tǒng)登陸來(lái)接觸數(shù)據(jù)庫(kù)的話,可以在賬號(hào)管理中把系統(tǒng)賬號(hào)“BUILTIN\Administrators”刪除。不過(guò)這樣做的結(jié)果是一旦sa賬號(hào)忘記密碼的話,就沒(méi)有辦法來(lái)恢復(fù)了。 
很多主機(jī)使用數(shù)據(jù)庫(kù)應(yīng)用只是用來(lái)做查詢、修改等簡(jiǎn)單功能的,請(qǐng)根據(jù)實(shí)際需要分配賬號(hào),并賦予僅僅能夠滿足應(yīng)用要求和需要的權(quán)限。比如,只要查詢功能的,那么就使用一個(gè)簡(jiǎn)單的public賬號(hào)能夠select就可以了。 
3、加強(qiáng)數(shù)據(jù)庫(kù)日志的記錄。 
審核數(shù)據(jù)庫(kù)登錄事件的“失敗和成功”,在實(shí)例屬性中選擇“安全性”,將其中的審核級(jí)別選定為全部,這樣在數(shù)據(jù)庫(kù)系統(tǒng)和操作系統(tǒng)日志里面,就詳細(xì)記錄了所有賬號(hào)的登錄事件。如圖: 
請(qǐng)定期查看SQL Server日志檢查是否有可疑的登錄事件發(fā)生,或者使用DOS命令。 
findstr /C:"登錄" d:\Microsoft SQL Server\MSSQL\LOG\*.* 
4、管理擴(kuò)展存儲(chǔ)過(guò)程 
對(duì)存儲(chǔ)過(guò)程進(jìn)行大手術(shù),并且對(duì)賬號(hào)調(diào)用擴(kuò)展存儲(chǔ)過(guò)程的權(quán)限要慎重。其實(shí)在多數(shù)應(yīng)用中根本用不到多少系統(tǒng)的存儲(chǔ)過(guò)程,而SQL Server的這么多系統(tǒng)存儲(chǔ)過(guò)程只是用來(lái)適應(yīng)廣大用戶需求的,所以請(qǐng)刪除不必要的存儲(chǔ)過(guò)程,因?yàn)橛行┫到y(tǒng)的存儲(chǔ)過(guò)程能很容易地被人利用起來(lái)提升權(quán)限或進(jìn)行破壞。 
如果你不需要擴(kuò)展存儲(chǔ)過(guò)程xp_cmdshell請(qǐng)把它去掉。使用這個(gè)SQL語(yǔ)句: 
use master 
sp_dropextendedproc 'xp_cmdshell' 
xp_cmdshell是進(jìn)入操作系統(tǒng)的最佳捷徑,是數(shù)據(jù)庫(kù)留給操作系統(tǒng)的一個(gè)大后門。如果你需要這個(gè)存儲(chǔ)過(guò)程,請(qǐng)用這個(gè)語(yǔ)句也可以恢復(fù)過(guò)來(lái)。 sp_addextendedproc 'xp_cmdshell', 'xpsql70.dll' 
如果你不需要請(qǐng)丟棄OLE自動(dòng)存儲(chǔ)過(guò)程(會(huì)造成管理器中的某些特征不能使用),這些過(guò)程包括如下: 
Sp_OACreate Sp_OADestroy Sp_OAGetErrorInfo Sp_OAGetProperty 
Sp_OAMethod Sp_OASetProperty Sp_OAStop 
去掉不需要的注冊(cè)表訪問(wèn)的存儲(chǔ)過(guò)程,注冊(cè)表存儲(chǔ)過(guò)程甚至能夠讀出操作系統(tǒng)管理員的密碼來(lái),如下: 
Xp_regaddmultistring Xp_regdeletekey Xp_regdeletevalue Xp_regenumvalues 
Xp_regread Xp_regremovemultistring Xp_regwrite 
還有一些其他的擴(kuò)展存儲(chǔ)過(guò)程,你也最好檢查檢查。 
在處理存儲(chǔ)過(guò)程的時(shí)候,請(qǐng)確認(rèn)一下,避免造成對(duì)數(shù)據(jù)庫(kù)或應(yīng)用程序的傷害。 
5、使用協(xié)議加密 
SQL Server 2000使用的Tabular Data Stream協(xié)議來(lái)進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)交換,如果不加密的話,所有的網(wǎng)絡(luò)傳輸都是明文的,包括密碼、數(shù)據(jù)庫(kù)內(nèi)容等等,這是一個(gè)很大的安全威脅。能被人在網(wǎng)絡(luò)中截獲到他們需要的東西,包括數(shù)據(jù)庫(kù)賬號(hào)和密碼。所以,在條件容許情況下,最好使用SSL來(lái)加密協(xié)議,當(dāng)然,你需要一個(gè)證書來(lái)支持。 
6、不要讓人隨便探測(cè)到你的TCP/IP端口 
默認(rèn)情況下,SQL Server使用1433端口監(jiān)聽,很多人都說(shuō)SQL Server配置的時(shí)候要把這個(gè)端口改變,這樣別人就不能很容易地知道使用的什么端口了??上?,通過(guò)微軟未公開的1434端口的UDP探測(cè)可以很容易知道SQL Server使用的什么TCP/IP端口了(請(qǐng)參考《深入探索SQL Server網(wǎng)絡(luò)連接的安全問(wèn)題》)。 
不過(guò)微軟還是考慮到了這個(gè)問(wèn)題,畢竟公開而且開放的端口會(huì)引起不必要的麻煩。在實(shí)例屬性中選擇TCP/IP協(xié)議的屬性。選擇隱藏 SQL Server 實(shí)例。如果隱藏了 SQL Server 實(shí)例,則將禁止對(duì)試圖枚舉網(wǎng)絡(luò)上現(xiàn)有的 SQL Server 實(shí)例的客戶端所發(fā)出的廣播作出響應(yīng)。這樣,別人就不能用1434來(lái)探測(cè)你的TCP/IP端口了(除非用Port Scan)。 
7、修改TCP/IP使用的端口 
請(qǐng)?jiān)谏弦徊脚渲玫幕A(chǔ)上,更改原默認(rèn)的1433端口。在實(shí)例屬性中選擇網(wǎng)絡(luò)配置中的TCP/IP協(xié)議的屬性,將TCP/IP使用的默認(rèn)端口變?yōu)槠渌丝?。如圖: 
9、拒絕來(lái)自1434端口的探測(cè) 
由于1434端口探測(cè)沒(méi)有限制,能夠被別人探測(cè)到一些數(shù)據(jù)庫(kù)信息,而且還可能遭到DOS攻擊讓數(shù)據(jù)庫(kù)服務(wù)器的CPU負(fù)荷增大,所以對(duì)Windows 2000操作系統(tǒng)來(lái)說(shuō),在IPSec過(guò)濾拒絕掉1434端口的UDP通訊,可以盡可能地隱藏你的SQL Server。 
10、對(duì)網(wǎng)絡(luò)連接進(jìn)行IP限制 
SQL Server 2000數(shù)據(jù)庫(kù)系統(tǒng)本身沒(méi)有提供網(wǎng)絡(luò)連接的安全解決辦法,但是Windows 2000提供了這樣的安全機(jī)制。使用操作系統(tǒng)自己的IPSec可以實(shí)現(xiàn)IP數(shù)據(jù)包的安全性。請(qǐng)對(duì)IP連接進(jìn)行限制,只保證自己的IP能夠訪問(wèn),也拒絕其他IP進(jìn)行的端口連接,把來(lái)自網(wǎng)絡(luò)上的安全威脅進(jìn)行有效的控制。 
關(guān)于IPSec的使用請(qǐng)參看:http://www.microsoft.com/china/tech...ty/ipsecloc.asp 
上面主要介紹的一些SQL Server的安全配置,經(jīng)過(guò)以上的配置,可以讓SQL Server本身具備足夠的安全防范能力。當(dāng)然,更主要的還是要加強(qiáng)內(nèi)部的安全控制和管理員的安全培訓(xùn),而且安全性問(wèn)題是一個(gè)長(zhǎng)期的解決過(guò)程,還需要以后進(jìn)行更多的安全維護(hù)。

 





    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多