使用触发器对SQL表进行预筛选
我有以下触发因素:使用触发器对SQL表进行预筛选,sql,sql-server-2008,triggers,Sql,Sql Server 2008,Triggers,我有以下触发因素: ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update] ON [dbo].[DIENSTLEISTUNG] INSTEAD OF UPDATE AS BEGIN SET NOCOUNT ON; INSERT INTO [DIENSTLEISTUNG] (BEZEICHNUNG, MENGENEINHEIT, PREIS, BESCHREIBUNG, VORLAUFZEIT, AZ
ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update]
ON [dbo].[DIENSTLEISTUNG]
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [DIENSTLEISTUNG] (BEZEICHNUNG, MENGENEINHEIT,
PREIS, BESCHREIBUNG, VORLAUFZEIT,
AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR,
AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID,
UPDATE_USER, UPDATE_DATE, RUESTZEIT,
PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER,
ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH,FLAG)
SELECT BEZEICHNUNG, MENGENEINHEIT,
PREIS, BESCHREIBUNG, VORLAUFZEIT,
AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR,
AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID,
UPDATE_USER,GETDATE(),RUESTZEIT,
PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER,
ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH,
0
FROM INSERTED
UPDATE DIENSTLEISTUNG
SET DIENSTLEISTUNG.FLAG = 1
FROM DIENSTLEISTUNG
INNER JOIN INSERTED
ON INSERTED.ID = DIENSTLEISTUNG.ID
SET NOCOUNT OFF;
END
如果原始行发生更改,触发器将使用新ID复制整行。它还在新行和旧行中设置一个标志(旧行获取标志=1,新行标志=0)
是否可以从触发器中筛选这些行,使其仅返回标志为0的新行
如果是,我怎么做
提前谢谢 如果您要求的是选择触发器,则不支持,MS SQL Server不支持选择触发器 但是,您可以使用一个视图,该视图只返回表中
标志
列为1的行,类似于
create view dbo.DIENSTLEISTUNG_Flagged
as
select * from DIENSTLEISTUNG
where FLAG=1
但是,我建议为历史记录增加一个表,而不是只保留它们。这样,您可以添加其他字段,如时间戳、更改行的用户或更改行的应用程序等。类似于(触发器的伪代码)的东西
请注意,这也会将您的“而非”触发器(纯邪恶)转换为常规触发器(稍微不那么邪恶)我想您可能是想先更新现有行,然后插入标记为0的新行
ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update]
ON [dbo].[DIENSTLEISTUNG]
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE d
SET FLAG = 1
FROM dbo.DIENSTLEISTUNG AS d
INNER JOIN inserted AS i
ON i.ID = d.ID;
INSERT INTO dbo.[DIENSTLEISTUNG]
(
BEZEICHNUNG, MENGENEINHEIT,
PREIS, BESCHREIBUNG, VORLAUFZEIT,
AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR,
AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID,
UPDATE_USER, UPDATE_DATE, RUESTZEIT,
PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER,
ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH,FLAG
)
SELECT BEZEICHNUNG, MENGENEINHEIT,
PREIS, BESCHREIBUNG, VORLAUFZEIT,
AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR,
AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID,
UPDATE_USER,GETDATE(),RUESTZEIT,
PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER,
ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 0
FROM inserted;
END
您的触发器不是“he”,也不是“返回行”。我也不明白插入flag=0,然后在插入后将其更新为1的目的。你的意思是先执行插入,然后将标志设置为0吗?为什么是
而不是触发器纯粹是邪恶的?@ypercube触发器通常被称为邪恶的,因为它们往往会产生无形的副作用,隐藏在幕后,因此通常很难调试而不是
触发器增加了副作用是唯一剩下的东西的混合,实际上,计算机没有做我明确指示它做的事情。虽然我不喜欢触发器(出于您提到的原因),但我认为在SQL Server中经常使用而不是触发器,因为在
触发器之前没有
。@SWeko我发现你的“纯粹邪恶”断言是一个误导性的、过于宽泛的陈述。有时,这比常规触发要好得多。为什么?假设我在插入时有一个触发器。我插入1000行。然后我的触发器意识到这些行违反了一些业务规则。太好了,现在我们开始后退。用一个代替触发器,我们可以阻止所有的工作,两次!我在几个场景中使用了instead of触发器,并发现它们非常有价值和有用(尽管,像after触发器和许多其他功能一样,它们可能被误用/误解/低估)。
ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update]
ON [dbo].[DIENSTLEISTUNG]
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE d
SET FLAG = 1
FROM dbo.DIENSTLEISTUNG AS d
INNER JOIN inserted AS i
ON i.ID = d.ID;
INSERT INTO dbo.[DIENSTLEISTUNG]
(
BEZEICHNUNG, MENGENEINHEIT,
PREIS, BESCHREIBUNG, VORLAUFZEIT,
AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR,
AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID,
UPDATE_USER, UPDATE_DATE, RUESTZEIT,
PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER,
ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH,FLAG
)
SELECT BEZEICHNUNG, MENGENEINHEIT,
PREIS, BESCHREIBUNG, VORLAUFZEIT,
AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR,
AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID,
UPDATE_USER,GETDATE(),RUESTZEIT,
PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER,
ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 0
FROM inserted;
END