How to prevent a table from being truncated or dropped

  • Hey guys, had one of my team members drop our main table by accident. Is there a way to prevent a table from being truncated or dropped? I tried adding a foreign key which allows nulls in a test table but it allowed me to truncate the table.

  • The foreign key should allow you to prevent truncates. To prevent dropping tables, you can use the a DDL trigger.

    CREATE TABLE TriggerTest( id int)

    GO

    CREATE TRIGGER T_Avoid_Drop_Table ON DATABASE

    FOR DROP_TABLE

    AS

    PRINT 'You must disable a trigger to drop tables!'

    ROLLBACK TRANSACTION

    GO

    DROP TABLE TriggerTest

    GO

    DISABLE TRIGGER T_Avoid_Drop_Table ON DATABASE

    GO

    DROP TABLE TriggerTest;

    IF OBJECT_ID( 'TriggerTest') IS NULL

    PRINT 'Success';

    GO

    DROP TRIGGER T_Avoid_Drop_Table ON DATABASE

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • dndaughtery (7/20/2016)


    Hey guys, had one of my team members drop our main table by accident. Is there a way to prevent a table from being truncated or dropped? I tried adding a foreign key which allows nulls in a test table but it allowed me to truncate the table.

    To best answer this question we need some context about where this needs to be done and who we are attempting to block.

    First, dropping or truncating requires either DB_OWNER database role, SYSADMIN server role, or explicit permissions granted to user on the object. None of these should normally be granted to a user in the production environment. If this is a production environment then read up on best practices regarding how to enforce "least privilege", which you can find in various articles and posts here in SQLServerCentral.

    Are you asking how to prevent certain types of operations from occurring in development where users can have elevated permissions?

    "Do not seek to follow in the footsteps of the wise. Instead, seek what they sought." - Matsuo Basho

  • Quick thought, foreign key constraint to the table from a pseudo table on a column with a default value constraint will do the trick.

    😎

    Edit: Typo

  • No more tears.

    ALTER SERVER ROLE [sysadmin] DROP MEMBER [<USER_NAME>];

    USE <DB_NAME>;

    ALTER ROLE [db_owner] DROP MEMBER [<USER_NAME>];

    "Do not seek to follow in the footsteps of the wise. Instead, seek what they sought." - Matsuo Basho

  • This was removed by the editor as SPAM

  • Eric M Russell (7/20/2016)


    dndaughtery (7/20/2016)


    Hey guys, had one of my team members drop our main table by accident. Is there a way to prevent a table from being truncated or dropped? I tried adding a foreign key which allows nulls in a test table but it allowed me to truncate the table.

    To best answer this question we need some context about where this needs to be done and who we are attempting to block.

    First, dropping or truncating requires either DB_OWNER database role, SYSADMIN server role, or explicit permissions granted to user on the object. None of these should normally be granted to a user in the production environment. If this is a production environment then read up on best practices regarding how to enforce "least privilege", which you can find in various articles and posts here in SQLServerCentral.

    Are you asking how to prevent certain types of operations from occurring in development where users can have elevated permissions?

    ALTER on the schema will also provide the necessary permission too so check for that

    -----------------------------------------------------------------------------------------------------------

    "Ya can't make an omelette without breaking just a few eggs" πŸ˜‰

  • JasonClark (8/23/2016)


    Try to run the below code to prevent accidental delete:

    CREATE TRIGGER [TR_ProtectCriticalTables]

    ON DATABASE

    FOR

    DROP_TABLE

    AS

    DECLARE @eventData XML,

    @uname NVARCHAR(50),

    @oname NVARCHAR(100),

    @otext VARCHAR(MAX),

    @etype NVARCHAR(100),

    @edate DATETIME

    SET @eventData = eventdata()

    SELECT

    @edate=GETDATE(),

    @uname=@eventData.value('data(/EVENT_INSTANCE/UserName)[1]', 'SYSNAME'),

    @oname=@eventData.value('data(/EVENT_INSTANCE/ObjectName)[1]', 'SYSNAME'),

    @otext=@eventData.value('data(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]',

    'VARCHAR(MAX)'),

    @etype=@eventData.value('data(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)')

    IF @oname IN ('tblBananas','tblApples','tblOranges')

    BEGIN

    DECLARE @err varchar(100)

    SET @err = 'Table ' + @oname + ' is super duper protected and cannot be dropped.'

    RAISERROR (@err, 16, 1) ;

    ROLLBACK;

    END

    GO

    ENABLE TRIGGER [TR_ProtectCriticalTables] ON DATABASE

    Lowell? Isn't this yours?

    β€œWrite the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Depending on how strong of a lock you want - the low end could be as simple as putting up a schema-bound view that references the table you don't want dropped.

    ----------------------------------------------------------------------------------
    Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?

  • ChrisM@Work (8/23/2016)


    JasonClark (8/23/2016)


    Try to run the below code to prevent accidental delete:

    CREATE TRIGGER [TR_ProtectCriticalTables]

    ON DATABASE

    FOR

    DROP_TABLE

    AS

    DECLARE @eventData XML,

    @uname NVARCHAR(50),

    @oname NVARCHAR(100),

    @otext VARCHAR(MAX),

    @etype NVARCHAR(100),

    @edate DATETIME

    SET @eventData = eventdata()

    SELECT

    @edate=GETDATE(),

    @uname=@eventData.value('data(/EVENT_INSTANCE/UserName)[1]', 'SYSNAME'),

    @oname=@eventData.value('data(/EVENT_INSTANCE/ObjectName)[1]', 'SYSNAME'),

    @otext=@eventData.value('data(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]',

    'VARCHAR(MAX)'),

    @etype=@eventData.value('data(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)')

    IF @oname IN ('tblBananas','tblApples','tblOranges')

    BEGIN

    DECLARE @err varchar(100)

    SET @err = 'Table ' + @oname + ' is super duper protected and cannot be dropped.'

    RAISERROR (@err, 16, 1) ;

    ROLLBACK;

    END

    GO

    ENABLE TRIGGER [TR_ProtectCriticalTables] ON DATABASE

    Lowell? Isn't this yours?

    yes it is Chris; it's a decent example from a post year or so ago: http://www.sqlservercentral.com/Forums/Topic1141863-338-1.aspx

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • Eric M Russell (7/20/2016)


    dndaughtery (7/20/2016)


    Hey guys, had one of my team members drop our main table by accident. Is there a way to prevent a table from being truncated or dropped? I tried adding a foreign key which allows nulls in a test table but it allowed me to truncate the table.

    To best answer this question we need some context about where this needs to be done and who we are attempting to block.

    First, dropping or truncating requires either DB_OWNER database role, SYSADMIN server role, or explicit permissions granted to user on the object. None of these should normally be granted to a user in the production environment. If this is a production environment then read up on best practices regarding how to enforce "least privilege", which you can find in various articles and posts here in SQLServerCentral.

    Are you asking how to prevent certain types of operations from occurring in development where users can have elevated permissions?

    This was also my thought. We do not allow anyone to have anything other than read access to production data with their everyday ID. DBA's have special ID's with the rights to alter data, and they only run scripts that have been promoted through an approval process. This really minimizes the risk of inadvertent data loss.

  • Regardless of the method used to prevent a table drop, there should still be regularly practiced drills where you assume a catastrophe of some sort. That means disaster recovery drills where you back up the log, ..., and do a test restore from backup. This just to make sure you have all the steps down like clockwork to reduce data loss and minimise downtime. You also never know when a large back up might be corrupt. You dont want to know this when you actually need it.

    ----------------------------------------------------

  • Eric M Russell (7/20/2016)


    No more tears.

    ALTER SERVER ROLE [sysadmin] DROP MEMBER [<USER_NAME>];

    USE <DB_NAME>;

    ALTER ROLE [db_owner] DROP MEMBER [<USER_NAME>];

    Too funny. I'm surprised nobody else picked up on this one.

  • In all seriousness, I second this one. If this user's job does not include dropping or truncating tables, he/she should not have the right. If they are involved in moving code to the server, then a different solution is needed.

    EDIT: I should have hit "quote" instead of reply. This is in reference to the "no more tears" comment.

  • Granting developers and other users membership in the SYSADMIN role is like planting a Tree Of Good And Evil in the middle of the Garden If Eden and then commanding everyone never to eat from it.

    What do you think it going to happen?

    "Do not seek to follow in the footsteps of the wise. Instead, seek what they sought." - Matsuo Basho

Viewing 15 posts - 1 through 15 (of 17 total)

You must be logged in to reply to this topic. Login to reply