Reputation: 7240
I have a table with a PK
create table a(x int constraint PK_x primary key(x))
How do I make a DDL trigger that prevents the dropping of the PK?
alter table a drop constraint PK_x
I can't get if the constraint is a PK from EVENTDATA
<EVENT_INSTANCE>
<EventType>ALTER_TABLE</EventType>
<PostTime>2021-11-04T13:08:11.417</PostTime>
<SPID>73</SPID>
<ServerName>SQL2017</ServerName>
<LoginName>sa</LoginName>
<UserName>dbo</UserName>
<DatabaseName>(redacted)</DatabaseName>
<SchemaName>dbo</SchemaName>
<ObjectName>a</ObjectName>
<ObjectType>TABLE</ObjectType>
<AlterTableActionList>
<Drop>
<Constraints>
<Name>PK_x</Name>
</Constraints>
</Drop>
</AlterTableActionList>
<TSQLCommand>
<SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
<CommandText>alter table a drop constraint PK_x</CommandText>
</TSQLCommand>
</EVENT_INSTANCE>
Upvotes: 0
Views: 100
Reputation: 71203
You can use XQuery to get the Primary Key Constraint name, and check it against a list of constraints
CREATE OR ALTER TRIGGER ddl_trig_PrimaryKeys
ON DATABASE
FOR ALTER_TABLE
AS
DECLARE @PKname sysname = EVENTDATA().value('
(/EVENT_INSTANCE[ObjectType[text() = "TABLE"]][ObjectName[text() = "a"]]
/AlterTableActionList/Drop/Constraints/Name
/text()[. = "PK_x" or . = "PK_y"])[1]',
'nvarchar(max)');
IF @PKname IS NOT NULL
BEGIN
THROW 50000, 'Dropping Primary Key constraint has been forbidden by trigger', 0;
END;
GO
Whether this is altogether a good idea to implement, I will leave to you...
Upvotes: 1