Stop deletes on a table

  • Hi,

    I want to stop all users from deleting records from a table.

    I went into permissions on that table and removed the delete permission for all roles - but the users are still able to delete.

    Is there a way to force this?

  • You probably have users that have dbo rights. Those bypass all security checks. (Or users do the deletes through stored procedures that are owned by the table owner, in which case ownership chaining applies).

    A very crude way to prevent all deletes is to create a trigger that simply throws an error and rolls back the transaction.


    Hugo Kornelis, SQL Server/Data Platform MVP (2006-2016)
    Visit my SQL Server blog: https://sqlserverfast.com/blog/
    SQL Server Execution Plan Reference: https://sqlserverfast.com/epr/

  • Thanks. Hoping to avoid the trigger - are there any other options?

  • Hugo Kornelis (1/13/2016)


    You probably have users that have dbo rights. Those bypass all security checks. (Or users do the deletes through stored procedures that are owned by the table owner, in which case ownership chaining applies).

    A very crude way to prevent all deletes is to create a trigger that simply throws an error and rolls back the transaction.

    Simpler approach would be an INSTEAD OF DELETE trigger with an empty code block

    😎

  • Can you give me an example of empty code block?

    I tried using this trigger, it stopped the deletes on the parent table but deleted the records in the child tables.

    CREATE TRIGGER [dbo].[No_Delete_MedicalGroup] ON [dbo].[medical_group]

    WITH EXECUTE AS CALLER

    INSTEAD OF DELETE

    AS

    BEGIN

    SET NOCOUNT ON

    DECLARE @TN varchar(255)

    SELECT @TN = object_name(parent_obj)

    FROM sysobjects

    WHERE id = @@procid;

    SET @TN = 'Deletes not allowed for this table: ' + @TN;

    -- Add your code for checking the values from deleted

    IF EXISTS(select * from deleted where medical_group_id = 1)

    RAISERROR (@tn, 16, 1)

    END

    GO

  • Quick example

    😎

    USE tempdb;

    GO

    SET NOCOUNT ON;

    IF OBJECT_ID(N'dbo.TBL_TEST_DELETE_TRIGGER') IS NOT NULL DROP TABLE dbo.TBL_TEST_DELETE_TRIGGER;

    CREATE TABLE dbo.TBL_TEST_DELETE_TRIGGER

    (

    TDT_ID INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_DBO_TBL_TEST_DELETE_TRIGGER_TDT_ID PRIMARY KEY CLUSTERED

    ,TDT_XVAL INT NOT NULL

    );

    GO

    CREATE TRIGGER dbo.TRG_TEST_DELETE_TRIGGER_NO_DELETE

    ON dbo.TBL_TEST_DELETE_TRIGGER

    INSTEAD OF DELETE

    AS

    BEGIN

    DECLARE @X INT = 0;

    --RAISERROR ('NO DELETES ALLOWED!',0,0) WITH NOWAIT; --optional

    END

    GO

    INSERT INTO dbo.TBL_TEST_DELETE_TRIGGER(TDT_XVAL)

    VALUES (0),(1),(2),(3),(4),(5);

    SELECT

    TDT.TDT_ID

    ,TDT.TDT_XVAL

    FROM dbo.TBL_TEST_DELETE_TRIGGER TDT;

    DELETE

    FROM dbo.TBL_TEST_DELETE_TRIGGER;

    SELECT

    TDT.TDT_ID

    ,TDT.TDT_XVAL

    FROM dbo.TBL_TEST_DELETE_TRIGGER TDT;

  • Hello This is a sample empty code body for your reference :

    CREATE TRIGGER DeleteMedicalGroup ON dbo.MedicalGroup

    INSTEAD OF DELETE

    AS

    BEGIN

    ROLLBACK;

    END;

  • abdullah.zarour (1/13/2016)


    Hello This is a sample empty code body for your reference :

    CREATE TRIGGER DeleteMedicalGroup ON dbo.MedicalGroup

    INSTEAD OF DELETE

    AS

    BEGIN

    ROLLBACK;

    END;

    Don't do this, the rollback is neither needs nor safe, in fact why ever would you use it there?

    😎

  • But an INSTEAD OF DELETE trigger will prevent anything (users, stored procedures, the DBA) from completing delete operations on the table. Is that what you really want?

    If you only want to prevent users from performing ad-hoc deletes, then remove them from whatever role is granting them that permission. By default, users start in the PUBLIC role and can't select, insert, update, delete any table, until you add them to a role (ex: DB_DATAREADER, DBO, etc.) or you grant them specific permissions (ex: GRANT DELETE ON TABLENAME TO USERNAME).

    If your users are members of the SYSADMIN role, then you're in a bad place. Do something to make them angry, then they can kick YOU out of the database. So, you need to seriously read up on this role based security and permissions thing.

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

  • Eric M Russell (1/13/2016)


    But an INSTEAD OF DELETE trigger will prevent anything (users, stored procedures, the DBA) from completing delete operations on the table. Is that what you really want?

    If you only want to prevent users from performing ad-hoc deletes, then remove them from whatever role is granting them that permission. By default, users start in the PUBLIC role and can't select, insert, update, delete any table, until you add them to a role (ex: DB_DATAREADER, DBO, etc.) or you grant them specific permissions (ex: GRANT DELETE ON TABLENAME TO USERNAME).

    If your users are members of the SYSADMIN role, then you're in a bad place. Do something to make them angry, then they can kick YOU out of the database. So, you need to seriously read up on this role based security and permissions thing.

    Quota clear

    😎

    I want to stop all users from deleting records from a table.

  • Sounds like a security problem to me. You need to get on top of the permissions your users have and reign in the permissions for the users you are concerned about deleting rows.

    If these users are in the db_owner Role (same effect, but different from being dbo[/url]) then a simple bypass still allows them to delete whatever they want:

    ALTER TABLE dbo.MedicalGroup DISABLE TRIGGER DeleteMedicalGroup;

    DELETE FROM dbo.MedicalGroup;

    ALTER TABLE dbo.MedicalGroup ENABLE TRIGGER DeleteMedicalGroup;

    There are no special teachers of virtue, because virtue is taught by the whole community.
    --Plato

  • to stop some users from deleting records from a table

    DENY DELETE ON OBJECT::dbo.table_to_deny TO restricted_user;

  • johnwalker10 (1/13/2016)


    to stop some users from deleting records from a table

    DENY DELETE ON OBJECT::dbo.table_to_deny TO restricted_user;

    Some users, yes, but still not someone in the db_owner Role as they could create a stored procedure to do the delete and the DENY would be bypassed via Ownership Chaining.

    There are no special teachers of virtue, because virtue is taught by the whole community.
    --Plato

  • Thanks everyone - very intersting input.

    I ended up using:

    CREATE TRIGGER NoDeleteMedicalGroup ON dbo.Medical_Group

    INSTEAD OF DELETE

    AS

    BEGIN

    ROLLBACK;

    END;

    No items in the Medical group table should ever be deleted. So, this worked for our needs.

    Thanks again everyone - most helpful.

  • krypto69 (1/14/2016)


    Thanks everyone - very intersting input.

    I ended up using:

    CREATE TRIGGER NoDeleteMedicalGroup ON dbo.Medical_Group

    INSTEAD OF DELETE

    AS

    BEGIN

    ROLLBACK;

    END;

    No items in the Medical group table should ever be deleted. So, this worked for our needs.

    Thanks again everyone - most helpful.

    Quick advice, don't do a rollback in the trigger, no relevant transaction to undo. You are risking unpredictable behavior with this!

    😎

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

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