1) Add the user to db_ddladmin role (or db_owner)
2) Grant ALTER table permissions to the table(s) in question
I'm not really a fan of either of these approaches as the first gives far too much control to the user and I try to avoid giving object level permissions if possible.
An alternative is to make use of the EXECUTE AS clause and wrap your TRUNCATE statement within a stored procedure and grant permissions on that instead.
-- create a test database CREATE DATABASE TruncateTest
GOUSE TruncateTest
GO-- create a low privilege user to test withCREATE USER NoRights WITHOUT LOGIN
GO-- create a table to test againstCREATE TABLE dbo.TestData (Id INT IDENTITY(1,1))GO-- add some dummy dataINSERT INTO dbo.TestData DEFAULT VALUESGO 20-- check the data is okSELECT COUNT(*) FROM dbo.TestData
GO-- impersonate the test userEXECUTE AS USER = 'NoRights'GO-- try to issue the truncate commandTRUNCATE TABLE dbo.TestData
GOMsg 1088, LEVEL 16, State 7, Line 1
Cannot find the object "TestData" because it does not exist or you do not have permissions.-- switch back to my superuserREVERT
GO-- create a wrapper procedure to truncate the tableCREATE PROCEDURE dbo.TruncateTestDataAS
TRUNCATE TABLE dbo.TestData
GO-- grant execute to the test userGRANT EXECUTE ON dbo.TruncateTestData TO NoRights
GO-- impersonate the test userEXECUTE AS USER = 'NoRights'GO-- execute the procedureEXEC dbo.TruncateTestData
GOMsg 1088, Level 16, State 7, Procedure TruncateTestData, Line 4Cannot find the object "TestData" because it does not exist or you do not have permissions.-- switch back to my superuserREVERT
GO-- modify the procedure to execute in the context of the owner (dbo)ALTER PROCEDURE dbo.TruncateTestDataWITH EXECUTE AS OWNERAS
TRUNCATE TABLE dbo.TestData
GO-- impersonate the test userEXECUTE AS USER = 'NoRights'GO-- execute the procedureEXEC dbo.TruncateTestData
GO-- switch back to the superuserREVERT
GO-- check the dataSELECT COUNT(*) FROM dbo.TestData
GO-- tidy upDROP DATABASE TruncateTest
GO
No comments:
Post a Comment