范围触发器 - 雇主的工资e

问题描述 投票:0回答:1

我有一个表,我叫 FUNC 我的所有员工都在那里,我有另一个表,我可以注册不同的工作角色...... 每个雇员都必须有一个工作角色,我的工作角色表有它的ID,角色名称,角色的最低工资和最高工资。

我的工作角色表有它的ID,角色的名称,角色的最低工资和角色的最高工资。

我想创建一个触发器 检查 每次我给 提高 如果加薪幅度在 "最低工资和最高工资 "的范围内,则给某些员工加薪。

为了让大家更容易理解,我将展示我目前所做的工作......。

CREATE TABLE FUNC(
    IDFUNC INT IDENTITY,
    NAME VARCHAR(30) NOT NULL,
    SALARY MONEY NOT NULL,
    ID_JOB INT,
    IDGESTOR INT
    )
GO

CREATE TABLE JOB(
    IDJOB INT IDENTITY,
    NAMEJOB VARCHAR(10) UNIQUE,
    MINIMUM MONEY NOT NULL,
    MAXIMUM MONEY NOT NULL,
)

/* CONSTRAINTS*/

ALTER TABLE FUNC ADD CONSTRAINT PK_FUNC
PRIMARY KEY(IDFUNC)
GO

ALTER TABLE JOB ADD CONSTRAINT PK_JOB
PRIMARY KEY(IDJOB)
GO

ALTER TABLE FUNC ADD CONSTRAINT FK_GESTOR
FOREIGN KEY(IDGESTOR) REFERENCES FUNC(IDFUNC)
GO

ALTER TABLE FUNC ADD CONSTRAINT FK_FUNC_JOB
FOREIGN KEY(ID_JOB) REFERENCES JOB(IDJOB)
GO

用这些值来喂养表格。

INSERT INTO JOB VALUES('MANAGER',5000,10000)
INSERT INTO JOB VALUES('SUPERVISOR',4000,7000)
INSERT INTO JOB VALUES('LEADER',2000,5000)
INSERT INTO JOB VALUES('ANALYST',1200,4000)
GO

IDJOB       NAMEJOB    MINIMUM               MAXIMUM
----------- ---------- --------------------- ---------------------
1           MANAGER    5000,00               10000,00
2           SUPERVISOR 4000,00               7000,00
3           LEADER     2000,00               5000,00
4           ANALYST    1200,00               4000,00

/

INSERT INTO FUNC VALUES('Name1',7000,1,NULL)
INSERT INTO FUNC VALUES('Name2',5000,2,1)
INSERT INTO FUNC VALUES('Name3',5000,2,1)
INSERT INTO FUNC VALUES('Name4',3000,3,2)
INSERT INTO FUNC VALUES('Name5',3400,3,2)
INSERT INTO FUNC VALUES('Name6',2800,3,3)
INSERT INTO FUNC VALUES('Name7',3200,3,3)
INSERT INTO FUNC VALUES('Name8',2000,4,4)
INSERT INTO FUNC VALUES('Name9',1800,4,4)
INSERT INTO FUNC VALUES('Name10',1500,4,5)
INSERT INTO FUNC VALUES('Name11',1300,4,5)
INSERT INTO FUNC VALUES('Name12',3000,4,6)
INSERT INTO FUNC VALUES('Name13',2000,4,6)
INSERT INTO FUNC VALUES('Name14',1900,4,7)
INSERT INTO FUNC VALUES('Name15',2100,4,7)
GO

IDFUNC         NAME                           SALARY               ID_JOB      IDGESTOR
------------- ------------------------------ --------------------- ----------- -----------
1             Name1                          7000,00               1           NULL
2             Name2                          5000,00               2           1
3             Name3                          5000,00               2           1
4             Name4                          3000,00               3           2
5             Name5                          3400,00               3           2
6             Name6                          2800,00               3           3
7             Name7                          3200,00               3           3
8             Name8                          2000,00               4           4
9             Name9                          1800,00               4           4
10            Name10                         1500,00               4           5
11            Name11                         1300,00               4           5
12            Name12                         3000,00               4           6
13            Name13                         2000,00               4           6
14            Name14                         1900,00               4           7
15            Name15                         2100,00               4           7

终于创建了这个触发器。

CREATE TRIGGER TRG_Salary
ON FUNC
FOR INSERT, UPDATE
AS
    DECLARE
    @MINIMUM MONEY, @MAXIMUM MONEY, @SALARY MONEY, @IDCARGO INT

    SELECT @IDJOB = IDJOB FROM JOB
    INNER JOIN INSERTED I
    ON IDJOB = I.ID_JOB
    WHERE IDFUNC = I.IDFUNC

    SELECT @MINIMUM = MINIMUM, @MAXIMUM = MAXIMUM
    FROM JOB WHERE IDJOB = @IDJOB

    SELECT @SALARY = I.SALARY FROM INSERTED I

    IF(@SALARY <@MINIMUM)
    BEGIN

        RAISERROR ('Salary Must be Higher than Minimum',16,1)
        ROLLBACK TRANSACTION
    END

    IF(@SALARY > @MAXIMUM)
    BEGIN

        RAISERROR ('SALARIO Must Be Lower than Maximum',16,1)
        ROLLBACK TRANSACTION
    END
GO

当我只更新一行时,它就能正常工作... ...

例:当我只更新一行时,它就能正常工作......。

UPDATE FUNC SET SALARY = 15000 WHERE IDFUNC = 1
GO

它会显示一个错误,因为我的员工IDFUNC=1 应该收到5000到10000之间,因为他是一个经理

我的问题是,当我试图一次更新我所有的行... ...

就像我想给每个人加薪一样。

UPDATE FUNC SET SALARY = SALARY*1.1

更新功能不检查我的触发器内的条件,不管它是在我的范围内还是在我的范围外,都会更新工资......我有一个叫FUNC的表,里面有我所有的员工,我还有一个表,我可以注册不同的工作角色。

sql sql-server database-trigger
1个回答
2
投票

问题是 inserted 包含多行。与其他大多数数据库不同,SQL Server不支持 每行 触发器(使用 for each row 子句)。)

你需要一次性检查所有插入的行,如果有任何行没有通过检查,则全部拒绝。下面是一个使用条件聚合的方法。

create trigger trg_salary
on func
for insert, update
as
    declare @isfailed int

    select @isfailed = max(
        case when i.salary not between j.minimum and j.maximum 
            then 1 
            else 0 
        end
    )
    from inserted i
    inner join job j on j.idjob = i.idjob

    if(@isfailed = 1)
    begin
        raiserror ('salary must be belong to the minimum-maximum range',16,1)
        rollback transaction
    end

go

2
投票

这个 INSERTED 伪表包含0-N行,其中N是被insertedupdated的行数(可以是零!)。正因为如此,而且因为SQL是针对 "基于集合的操作 "进行优化的,所以你需要建立一个查询来测试你的错误条件。

然而正因为如此,除非你想返回一个错误列表,否则即使存在多个错误,你也只能返回1个错误。

另外,最好的做法是使用 THROW 而非 RAISERROR.

CREATE TRIGGER TRG_Salary ON FUNC
FOR INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @ERROR NVARCHAR(2048);

    SELECT TOP 1 @ERROR = CASE WHEN I.SALARY > MAXIMUM THEN 'SALARIO Must Be Lower than Maximum.' WHEN I.SALARY < MAXIMUM THEN 'SALARIO Must Be Higher than Minimum.' END
    FROM INSERTED I
    INNER JOIN JOB J on J.IDJOB = I.ID_JOB
    WHERE I.SALARY > MAXIMUM OR I.SALARY < MAXIMUM;

    IF @ERROR IS NOT NULL BEGIN
        ROLLBACK;
        THROW 51000, @ERROR, 1;  
    END;
END
GO

1
投票

SQL Fiddle

MS SQL Server 2017 模式设置:

CREATE TABLE FUNC(
    IDFUNC INT IDENTITY,
    NAME VARCHAR(30) NOT NULL,
    SALARY MONEY NOT NULL,
    ID_JOB INT,
    IDGESTOR INT
    )
GO

CREATE TABLE JOB(
    IDJOB INT IDENTITY,
    NAMEJOB VARCHAR(10) UNIQUE,
    MINIMUM MONEY NOT NULL,
    MAXIMUM MONEY NOT NULL,
)

/* CONSTRAINTS*/

ALTER TABLE FUNC ADD CONSTRAINT PK_FUNC
PRIMARY KEY(IDFUNC)
GO

ALTER TABLE JOB ADD CONSTRAINT PK_JOB
PRIMARY KEY(IDJOB)
GO

ALTER TABLE FUNC ADD CONSTRAINT FK_GESTOR
FOREIGN KEY(IDGESTOR) REFERENCES FUNC(IDFUNC)
GO

ALTER TABLE FUNC ADD CONSTRAINT FK_FUNC_JOB
FOREIGN KEY(ID_JOB) REFERENCES JOB(IDJOB)
GO

INSERT INTO JOB VALUES('MANAGER',5000,10000)
INSERT INTO JOB VALUES('SUPERVISOR',4000,7000)
INSERT INTO JOB VALUES('LEADER',2000,5000)
INSERT INTO JOB VALUES('ANALYST',1200,4000)
GO
INSERT INTO FUNC VALUES('Name1',7000,1,NULL)
INSERT INTO FUNC VALUES('Name2',5000,2,1)
INSERT INTO FUNC VALUES('Name3',5000,2,1)
INSERT INTO FUNC VALUES('Name4',3000,3,2)
INSERT INTO FUNC VALUES('Name5',3400,3,2)
INSERT INTO FUNC VALUES('Name6',2800,3,3)
INSERT INTO FUNC VALUES('Name7',3200,3,3)
INSERT INTO FUNC VALUES('Name8',2000,4,4)
INSERT INTO FUNC VALUES('Name9',1800,4,4)
INSERT INTO FUNC VALUES('Name10',1500,4,5)
INSERT INTO FUNC VALUES('Name11',1300,4,5)
INSERT INTO FUNC VALUES('Name12',3000,4,6)
INSERT INTO FUNC VALUES('Name13',2000,4,6)
INSERT INTO FUNC VALUES('Name14',1900,4,7)
INSERT INTO FUNC VALUES('Name15',2100,4,7)
GO

CREATE TRIGGER TRG_Salary
ON FUNC
FOR INSERT, UPDATE
AS

    IF EXISTS
    (
        SELECT 1
        FROM JOB J
        INNER JOIN INSERTED F
        ON J.IDJOB = F.ID_JOB
        WHERE F.Salary < J.Minimum OR F.Salary > J.Minimum
    )    
    BEGIN
        RAISERROR ('SALARIO Must Be Lower than Maximum and Greater than Minimum',16,1)
        ROLLBACK TRANSACTION
    END
GO

查询1:

--UPDATE FUNC SET SALARY = 15000 WHERE IDFUNC = 1

UPDATE FUNC SET SALARY = SALARY*1.1

结果:SALARIO必须低于最高值和高于最低值。

© www.soinside.com 2019 - 2024. All rights reserved.