gpt4 book ai didi

sql - 我需要优化我的第一个 T-SQL 更新触发器

转载 作者:行者123 更新时间:2023-12-03 00:00:05 25 4
gpt4 key购买 nike

如何在不使用大量变量的情况下重写此更新触发器?

我编写了第一个 SQL Server 触发器,它运行良好,但我认为,必须有一个更简单的解决方案。

如果 5 列中的至少一列发生更改,我会在另一个表中写入两个新行。第 1 行 = 旧的 Fahrer (=Driver) 和旧的 dispodate 和更新时间第 2 行 = 新的 Fahrer 和新的 dispodate 以及 updatedatetime我的解决方案只是foxpro-trigger的副本,但T-SQL中必须有更简单的解决方案来检查某一列是否更改。

ALTER TRIGGER [dbo].[MyTrigger]
ON [dbo].[tbldisposaetze]
AFTER UPDATE
AS
SET NOCOUNT ON;
/*SET XACT_ABORT ON
SET ARITHABORT ON
*/
DECLARE @oldfahrer varchar(10)
DECLARE @oldbus varchar(10)
DECLARE @olddispodat date
DECLARE @oldvzeit decimal(4,0)
DECLARE @oldbzeit decimal(4,0)
DECLARE @oldbeschreibk varchar(255)

DECLARE @newfahrer varchar(10)
DECLARE @newbus varchar(10)
DECLARE @newdispodat date
DECLARE @newvzeit decimal(4,0)
DECLARE @newbzeit decimal(4,0)
DECLARE @newbeschreibk varchar(255)

SELECT @oldfahrer = fahrer,@oldbeschreibk=beschreibk,@oldbus=bus,@oldbzeit=bzeit,@olddispodat=dispodat,@oldvzeit=vzeit
FROM DELETED D
SELECT @newfahrer = fahrer,@newbeschreibk=beschreibk,@newbus=bus,@newbzeit=bzeit,@newdispodat=dispodat,@newvzeit=vzeit
FROM inserted I

if @oldbeschreibk <> @newbeschreibk or @oldbus <> @newbus or @oldbzeit <> @newbzeit or @oldfahrer <> @newfahrer or @oldvzeit <> @newvzeit
begin
IF (SELECT COUNT(*) FROM tbldispofahrer where fahrer=@oldfahrer and dispodat=@olddispodat) > 0
update tbldispofahrer set laenderung = GETDATE() where fahrer=@oldfahrer and dispodat=@olddispodat
else
INSERT into tbldispofahrer (fahrer,dispodat,laenderung) VALUES (@oldfahrer,@olddispodat,getdate())

IF (SELECT COUNT(*) FROM tbldispofahrer where fahrer=@newfahrer and dispodat=@newdispodat) > 0
update tbldispofahrer set laenderung = GETDATE() where fahrer=@newfahrer and dispodat=@newdispodat
else
INSERT into tbldispofahrer (fahrer,dispodat,laenderung) VALUES (@newfahrer,@newdispodat,getdate())
end

最佳答案

我假设您拥有 SQL Server 2008 或更高版本。您可以在一条语句中完成这一切,无需任何变量。

您可以在 where 子句中轻松完成所有工作,而不是首先获取变量并查看它们是否不匹配。正如人们在评论中所说,您可以将多行作为插入和删除的一部分。为了确保您使用的是相同的更新行,您需要通过主键进行匹配。

为了插入或更新行,我使用 MERGE 语句。合并的来源是与上面的 where 子句的联合,联合中的顶部表具有旧的 fahrer,底部表具有新的 Farher。就像您的内部 IF 一样,现有行在 farher 和 dispodat 上进行匹配,并适当插入或更新。

我注意到的一件事是,在您的示例中,newfahrer 和 oldfahrer 可能完全相同,因此只应发生一次插入或更新(即,如果只有 bzeit 不同)。联合应防止尝试插入重复数据。我相信如果有的话合并会出错。

MERGE tbldispofahrer AS tgt
USING (
SELECT d.farher, d.dispodat, GETDATE() [laenderung]
INNER JOIN inserted i ON i.PrimaryKey = d.PrimaryKey
AND (i.fahrer <> d.fahrer OR i.beschreibk <> d.beschreik ... )
UNION
SELECT i.farher, i.dispodat, GETDATE() [laenderung]
INNER JOIN inserted i ON i.PrimaryKey = d.PrimaryKey
AND (i.fahrer <> d.fahrer OR i.beschreibk <> d.beschreik ... )
) AS src (farher, dispodat, laenderung)
ON tgt.farher = src.farher AND tgt.dispodat = src.dispodat
WHEN MATCHED THEN UPDATE SET
laenderung = GETDATE()
WHEN NOT MATCHED THEN
INSERT (fahrer,dispodat,laenderung)
VALUES (src.fahrer, src.dispodat, src.laenderung)

关于sql - 我需要优化我的第一个 T-SQL 更新触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27828749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com