【发布时间】:2020-06-03 21:12:21
【问题描述】:
我有一张我称为FUNC 的表,我的所有员工都在其中,我还有另一个表可以注册不同的工作角色...每个员工都必须有一个工作角色。
我的工作角色表有它的ID、角色名称、角色的最低工资和角色的最高工资。
如果加薪在“最低工资和最高工资”范围内,我想创建一个触发器,每次我给某个员工RAISE时检查 .
为了更容易理解,我将展示我到目前为止所做的事情......
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 的 Employee 应该收到 5000 到 10000 之间,因为他是经理
我的问题是当我尝试一次更新所有行时...
如果我想为每个人加薪
UPDATE FUNC SET SALARY = SALARY*1.1
更新函数不检查我的触发器内的条件并更新薪水,无论它是在我的范围内还是在我的范围之外......
【问题讨论】:
-
INSERTED有多行 - 您的代码仅选择 1 个随机@IDJOB- 您需要使用基于集合的方法处理inserted。 -
您是否有任何链接解释如何使用“基于方法”以便我理解?
-
一切 SQL 都应该使用“基于集合的方法”——有很多链接,例如this
-
从设计/操作的角度来看,“部分”成功的触发器是噩梦。触发器旨在强制执行数据约束,而不是执行用户输入验证。我希望细微的差别很清楚。
-
如果您需要在 SQL 中执行此验证,那么我建议您编写一个 SP 或一个函数,可以为每个员工检查并显示相关错误之前您执行更新。
标签: sql sql-server sql-update sql-insert database-trigger