use*_*696 2 trigger sql-server sql-server-2017
我有这 3 个表:
构造函数员工
EID (员工 ID)作为主键和其他键。项目
PID 作为主键和其他键。项目建设者员工
PID并EID作为其他表的外键。每个ConstructorEmployee可以在几个Projects. 我需要创建一个触发器,如果项目已被删除,我需要删除所有ConstructorEmployee 该工作仅在这个项目上。我需要从ConstructorEmployee表中删除它们。
我正在研究 SQL Server 2017。
我假设您的表架构类似于下一个:
CREATE TABLE ConstructorEmployee
(
EID int PRIMARY KEY
);
CREATE TABLE Project
(
PID int PRIMARY KEY
);
CREATE TABLE ProjectConstructorEmployee
(
PID int,
EID int,
CONSTRAINT PK_PCE PRIMARY KEY(PID, EID),
CONSTRAINT FK_P FOREIGN KEY (PID) REFERENCES Project (PID),
CONSTRAINT FK_CE FOREIGN KEY (EID) REFERENCES ConstructorEmployee (EID)
);
GO
Run Code Online (Sandbox Code Playgroud)
ProjectConstructorEmployee桌子上有两个外键。
现在让我添加一些数据 3 名员工和 3 个项目,但 Employee=1 仅适用于第一个项目。
INSERT INTO ConstructorEmployee VALUES (1), (2),(3);
GO
INSERT INTO Project VALUES (1), (2), (3);
GO
-- EID = 1 worked in PID 1 only
INSERT INTO ProjectConstructorEmployee VALUES
(1, 1), (1, 2), (2, 2), (2, 3), (3, 2), (3, 3);
GO
Run Code Online (Sandbox Code Playgroud)
下一个查询返回仅在一个项目中工作过的员工列表,在本例中为 PID=1
-- Employees working on PID=1 that didn't work in any other project
SELECT EID
FROM ProjectConstructorEmployee
WHERE EID IN (SELECT EID FROM ProjectConstructorEmployee WHERE PID=1)
GROUP BY EID
HAVING COUNT(*) = 1
GO
| EID |
| --: |
| 1 |
Run Code Online (Sandbox Code Playgroud)
我需要创建一个触发器...
不,不要使用触发器,让我建议使用存储过程,这对您和任何其他开发人员来说总是更清楚。或者,如果您想使用触发器,请使用调用此过程的 BEFORE DELETE 触发器。
CREATE PROCEDURE DeleteProject(@PID int)
AS
BEGIN
BEGIN TRY
DECLARE @employee TABLE (EID int);
BEGIN TRANSACTION;
-- save a list of employees that only worked in this proejct
-- due to FOREIGN KEYS you can't delete ConstructorEmployee table
-- until you have deleted the other both.
INSERT INTO @employee
SELECT EID
FROM ProjectConstructorEmployee
WHERE EID IN (SELECT EID
FROM ProjectConstructorEmployee
WHERE PID = @PID)
GROUP BY EID
HAVING COUNT(*) = 1;
DELETE FROM ProjectConstructorEmployee
WHERE PID = @PID;
DELETE FROM Project
WHERE PID = @PID;
DELETE FROM ConstructorEmployee
WHERE EID IN (SELECT EID FROM @employee);
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
-- Your error handler
THROW;
END CATCH
END
GO
Run Code Online (Sandbox Code Playgroud)
好的,让我通过删除项目 1 和 2 来尝试:
EXEC DeleteProject @PID = 1;
EXEC DeleteProject @PID = 2;
SELECT * FROM ConstructorEmployee;
SELECT * FROM Project;
SELECT * FROM ProjectConstructorEmployee;
GO
Run Code Online (Sandbox Code Playgroud)
剩余员工:
| EID |
| --: |
| 2 |
| 3 |
Run Code Online (Sandbox Code Playgroud)
项目:
| PID |
| --: |
| 3 |
Run Code Online (Sandbox Code Playgroud)
和项目员工:
PID | EID
--: | --:
3 | 2
3 | 3
Run Code Online (Sandbox Code Playgroud)
db<>在这里摆弄
但是……您确定要删除所有这些信息吗?
您将丢失所有项目的历史记录,员工和项目将从您的数据库中消失。也许你可以设置一个像 Active(Yes/No) 这样的标志,让这个信息可供以后想要恢复的人使用。
| 归档时间: |
|
| 查看次数: |
597 次 |
| 最近记录: |