1. 程式人生 > >限定某個使用者不能delete,drop,truncate某個表

限定某個使用者不能delete,drop,truncate某個表

-------------- 測試表 Begin ----------------
--這裡的測試庫為 tempdb
--弄清楚之後,修改相關程式碼,再上正式生產環境操作
USE tempdb
GO
IF EXISTS(SELECT * FROM sys.triggers AS t WHERE t.name='TR_Safety_Table')
BEGIN
	DROP TRIGGER TR_Safety_Table ON DATABASE;
END
GO
IF OBJECT_ID('dbo.t1') IS NOT NULL
	DROP TABLE dbo.t1
GO
CREATE TABLE dbo.t1(
	id INT IDENTITY(1,1) PRIMARY KEY,
	[Type] INT	
)
GO
SET NOCOUNT ON
INSERT INTO dbo.t1([Type]) VALUES(1)
INSERT INTO dbo.t1([Type]) VALUES(2)
GO

-------------- 測試表 End ----------------

--1. 建立登入名
USE [master]
GO
--刪除所有 testUser 的連線
DECLARE @sql NVARCHAR(MAX)
SELECT @sql=ISNULL(@sql,'')+'kill '+CAST(s.spid AS VARCHAR(50))+'
' FROM sys.sysprocesses AS s WHERE s.spid>50 AND s.loginame='testUser'
EXEC(@sql)

IF EXISTS(SELECT * FROM sys.syslogins AS s WHERE NAME='testUser')
BEGIN
	DROP LOGIN [testUser]	
END
GO
CREATE LOGIN testUser WITH PASSWORD=N'testUser', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO

--2. 進入需要授權的庫,建立使用者名稱並授權
USE tempdb
GO
IF EXISTS(SELECT 1 FROM sys.database_principals WHERE NAME='testUser' AND type_desc='SQL_USER')
	DROP USER testUser
GO
CREATE USER testUser FOR LOGIN testUser
GO
EXEC sp_addrolemember N'db_owner', N'testUser'
GO
DENY DELETE,ALTER ON dbo.t1 TO testUser
GO
IF EXISTS(SELECT * FROM sys.triggers AS t WHERE t.name='TR_Safety_Table')
BEGIN
	DROP TRIGGER TR_Safety_Table ON DATABASE;
END
GO
-- =============================================
-- Author:      
-- Create date: <2010-04-03>
-- Description:	<除了sa使用者,禁止其他資料庫使用者 ALTER TABLE 和DROP TABLE的許可權>
-- =============================================
CREATE TRIGGER TR_Safety_Table 
ON DATABASE 
FOR DROP_TABLE, ALTER_TABLE
AS 
BEGIN
	DECLARE @EVENTDATA XML;  
    SET @EVENTDATA = EVENTDATA();
	IF @EVENTDATA.value('(/EVENT_INSTANCE/EventType)[1]','nvarchar(max)') IN ('DROP_TABLE','ALTER_TABLE')
		and @EVENTDATA.value('(/EVENT_INSTANCE/LoginName)[1]','nvarchar(max)')='testUser'
		and @EVENTDATA.value('(/EVENT_INSTANCE/DatabaseName)[1]','nvarchar(max)')='tempdb'
		and @EVENTDATA.value('(/EVENT_INSTANCE/SchemaName)[1]','nvarchar(max)')='dbo'
		and @EVENTDATA.value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(max)')='t1'
		and @EVENTDATA.value('(/EVENT_INSTANCE/ObjectType)[1]','nvarchar(max)')='TABLE'
	BEGIN
		PRINT SUSER_SNAME()+'你無DROP TABLE 和 ALTER TABLE 的許可權!';
		ROLLBACK; 
	END
END
GO

--------------------- 用 testUser 使用者登入之後 -----------------------
USE tempdb
GO
DELETE FROM t1
/*
訊息 229,級別 14,狀態 5,第 8 行
拒絕了對物件 't1' (資料庫 'tempdb',架構 'dbo')的 DELETE 許可權。
*/
TRUNCATE TABLE t1
/*
訊息 1088,級別 16,狀態 7,第 9 行
找不到物件“t1”,因為它不存在或者您沒有所需的許可權。
*/
DROP TABLE t1
/*
testUser你無DROP TABLE 和 ALTER TABLE 的許可權!
訊息 3609,級別 16,狀態 2,第 3 行
事務在觸發器中結束。批處理已中止。
*/
SELECT * FROM t1
/*
id	Type
1	1
2	2
*/
UPDATE t1 SET [Type]=[Type]+1
/*
(2 行受影響)
*/
參考文件:點選開啟連結