0

我有一张带 PK 的桌子

create table a(x int constraint PK_x primary key(x))

如何制作防止 PK 丢失的 DDL 触发器?

alter table a drop constraint PK_x

如果约束是来自 EVENTDATA 的 PK,我无法获得

<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>
4

1 回答 1

1

您可以使用 XQuery 获取主键约束名称,并根据约束列表检查它

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

这是否完全是一个好主意,我会留给你......

于 2021-11-04T12:38:30.567 回答