验证触发器在 SQL 服务器中不起作用

Validation trigger not working in SQL Server

我正在为一个 class 项目开发触发器。

我有一个名为 salesman 的 table 和一个名为 type 的列。 table 中的所有员工当前的 typefullparttemp

触发器的目的是检查新插入行的 type 并确保它与已存在的三个行之一匹配。如果是,则应允许插入,否则应停止或回滚。感谢您提出任何想法!

这是代码的最新排列。

CREATE TRIGGER trg_validate_emp_type
ON salesman
FOR INSERT
AS
BEGIN
    DECLARE @job varchar (20)

    SELECT @job = (SELECT type FROM inserted)

    IF NOT EXISTS (SELECT 1 FROM salesman WHERE UPPER(type) = UPPER(@job))      
    BEGIN
        ROLLBACK TRANSACTION
        PRINT 'employee type not valid'
    END
END

如果您想检查列的值,有更有效的方法。 最佳实践是定义约束。 当值存储在 table 中时,则使用 FOREIGN KEY 约束;在其他情况下使用 CHECK 约束。

正如几个人所指出的,这看起来像是检查约束或外键的工作。

例如

create table salesman(id int primary key, type varchar(20) check (type in ('a','b')))

create table salesman_type (type varchar(20) primary key )
create table salesman(id int primary key, type varchar(20) references salesman_type)

但如果您真的想编写一个触发器来阻止插入 table 中尚不存在的值,您可以这样做:

    use tempdb
    go
    create table salesman
    (
      id int identity primary key, 
      type varchar(20) not null, 
      index ix_salesman_type(type) 
    )
    insert into salesman(id,type) values (1,'a')
    insert into salesman(id,type) values (2,'b')
    go
    CREATE OR ALTER TRIGGER trg_validate_emp_type
    ON salesman
    FOR INSERT
    AS
    BEGIN
    
        IF EXISTS 
        (
          SELECT * 
          FROM inserted 
          WHERE type not in
              (
                select type 
                from salesman
                where id not in (select id from inserted)
              )
        )
        BEGIN
           throw 50001, 'employee type not valid', 1;
        END
    END

go

insert into salesman(id,type) values (3,'c') -- fails

insert into salesman(id,type) values (3,'a') -- succeeds 

由于 XACT_ABORT 在触发器中默认为 ON,您可以简单地 THROW 而不是 ROLLBACK + PRINT,并且客户端会收到更好的错误消息。