如何使触发器与两个源表一起工作?
Posted
技术标签:
【中文标题】如何使触发器与两个源表一起工作?【英文标题】:How can I made a trigger work with two source tables? 【发布时间】:2021-08-15 14:16:01 【问题描述】:我无法让此触发器正常工作。我很少使用触发器,所以我对它们的理解可能有点偏离,因为我编写此代码的方式似乎应该有效(至少对我而言)但它没有。如果对 tblCollateralAssignment 进行了更新,则触发器正常工作并将所有信息保存在 tblCollateralAssignmentHistory 表中(包括来自 CustodianData 表的任何信息)。
但是,如果进行的更新仅涉及 CustodianData 表(例如,仅更新 CustodianFrom 字段)并且没有涉及 tblCollateralAssignemnt 中的任何字段,则触发器不起作用并且更新不会保存到 tblCollateralAssignmentHistory。
希望我只是忽略了一些小东西,但我一直盯着它看,不知所措。
ALTER TRIGGER [dbo].[Trigger_tblCollateralAssignmentToHistory]
ON [dbo].[tblCollateralAssignment] AFTER UPDATE
AS
SET NOCOUNT ON;
IF EXISTS ( SELECT ChainID FROM inserted ) AND EXISTS ( SELECT ChainID FROM deleted )
BEGIN
--This updates history with the changed records.
INSERT INTO dbo.tblCollateralAssignmentHistory
SELECT i.ChainID
,d.LoanNo
,d.FileDate as BeginFileDate
,i.FileDate as EndFileDate
,d.ModifiedBy
,d.RecordSource
,d.AssignmentNo
,d.AssignmentFrom
,d.AssignmentTo
,d.RecordedDate
,d.StatusPerTitle
,d.RecordedImage
,d.AtCustodian
,d.AOMComments
,d.IsVisible
,d.DocXNotarized
,d.AOMBook
,d.AOMDocumentNo
,d.AOMPage
,d.CorrectiveAssignment
,d.DocumentID
,d.DocumentDetails
,cd.CustodianUID
,cd.CustodianDocCode AS DocCode
,d.MASIdentified
,cd.CustodianExceptionDescription AS ExceptionDescription
,cd.CustodianFrom
,cd.CustodianTo
,cd.CustodianNotation
,cd.CustodianComments
FROM deleted as d
JOIN inserted as i on i.ChainID = d.ChainID
LEFT JOIN ExternalReports.CustodianData AS cd ON cd.ChainId = i.ChainID
END
--Clear out CorrectiveAssignment if the related ChainID IsVisible is set to false. This is a trigger enacted cascade delete for soft deleted chains. Edited records are also copied to history.
DECLARE @FileDate datetime = GETDATE();
UPDATE
dbo.tblCollateralAssignment
SET
CorrectiveAssignment = NULL,
FileDate = @FileDate
OUTPUT
inserted.ChainID,
deleted.LoanNo,
deleted.FileDate AS BeginFileDate,
@FileDate AS EndFileDate,
deleted.ModifiedBy,
deleted.RecordSource,
deleted.AssignmentNo,
deleted.AssignmentFrom,
deleted.AssignmentTo,
deleted.RecordedDate,
deleted.StatusPerTitle,
deleted.RecordedImage,
deleted.AtCustodian,
deleted.AOMComments,
deleted.IsVisible,
deleted.DocXNotarized,
deleted.AOMBook,
deleted.AOMDocumentNo,
deleted.AOMPage,
deleted.CorrectiveAssignment,
deleted.DocumentID,
deleted.DocumentDetails,
cd.CustodianUID,
cd.CustodianDocCode AS DocCode,
deleted.MASIdentified,
cd.CustodianExceptionDescription AS ExceptionDescription,
cd.CustodianFrom,
cd.CustodianTo,
cd.CustodianNotation,
cd.CustodianComments
INTO
dbo.tblCollateralAssignmentHistory
FROM
dbo.tblCollateralAssignment AS CorrectiveAssignment
LEFT JOIN
ExternalReports.CustodianData AS cd ON cd.ChainId = CorrectiveAssignment.ChainID
WHERE EXISTS
(select * from dbo.tblCollateralAssignment as DeletedAssignment where DeletedAssignment.IsVisible = 0 and DeletedAssignment.ChainID = CorrectiveAssignment.CorrectiveAssignment)
AND
CorrectiveAssignment is not null
AND EXISTS
(select * from inserted AS i where i.LoanNo = CorrectiveAssignment.LoanNo);
【问题讨论】:
触发器是高度特定于供应商的 - 所以请添加一个标签来指定您使用的是mysql
、postgresql
、sql-server
、oracle
还是db2
- 或完全不同的东西。
不确定您期望table A
上的触发器如何同时处理Table B
上的更新。您将需要在每个表上都有一个触发器。
我猜 OP 正在使用 MS SQL Server。
您好,很抱歉没有标记供应商。我正在使用 sql 服务器。 @Stu那么不可能使用单个触发器从两个源表中填充目标历史表吗?只能使用两个触发器来完成吗?基本上,我们过去只有 tblCollateralAssignment(保存最新信息),然后是 tblCollateralAssignmentHistory,它保存了 tblCollateralAssignment 中的所有条目。该数据通过触发器到达那里。但我们最近将 5 个字段从 tblCollateralAssignment 移出并移至 CustodianData。所以我试图让触发器工作。
难道不能使用单个触发器从两个源表中填充目标历史表吗? 是的; 只能使用两个触发器来完成? 是的
【参考方案1】:
希望这会奏效
CREATE OR REPLACE TRIGGER checkDuration
BEFORE INSERT OR UPDATE on offering
FOR EACH ROW
DECLARE
isFound NUMBER;
BEGIN
SELECT 1 INTO isFound FROM DUAL WHERE EXISTS (
SELECT * FROM Course c
WHERE c.courseId = :new.courseId AND c.duration = 5);
IF EXTRACT(MONTH FROM :new.startDate) = 12
THEN RAISE_APPLICATION_ERROR(-20001, 'Courses of five days duration cannot be run in December');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
【讨论】:
以上是关于如何使触发器与两个源表一起工作?的主要内容,如果未能解决你的问题,请参考以下文章