sql - 触发更新现有数据或在数据不存在时插入(多行支持)

标签 sql sql-server-2008 triggers

我有两个表,两个表都包含类似的“用户名”、“日期”和“时间”列。一个表(表 2)本质上是每个日期“时间”列的总和,其中 table1 每个日期可以有多个“时间”。

我无法控制用于将数据插入 table1 的任何语句,因此我认为执行此操作的最佳方法是在 table1 上使用触发器,该触发器插入更新 table2 取决于插入日期是否已存在行。 为此,类似以下内容就可以了:

IF NOT EXISTS(SELECT * FROM table2 WHERE date = @date/*date from inserted*/)
    --insert into table 2 here
ELSE
    --update table 2 here

但是,问题是我还需要触发器上的多行支持,这会导致之前的 IF 失败。一个想法是循环插入的每一行,但从我读到的内容来看,这将对性能产生很大影响,这是我想避免的(如果没有更好的方法,这是最后的手段)。

那么,有没有一种方法可以在不使用某种循环的情况下完成我需要的操作?

我将使用的插入示例:

INSERT INTO table2 (username, date, time)
SELECT i.username, i.date, SUM(w.time) FROM inserted AS i
JOIN (SELECT username, date, time FROM table1/*table with trigger*/) AS w 
ON w.date = i.date AND w.username = i.username 
GROUP BY i.username, i.date

预先感谢您的任何建议!

注意:我是 SQL 新手,如果我遗漏了任何内容/犯了明显的错误,我很抱歉!

编辑(解决方案):

工作解决方案(感谢@Ronak Vyas的回答)如下:

MERGE table2 AS m
USING (SELECT i.username, i.date, SUM(w.time) FROM inserted AS i
JOIN (SELECT username, date, time FROM table1/*table with trigger*/) AS w 
ON w.date = i.date AND w.username = i.username 
GROUP BY i.username, i.date) AS s
ON m.date = s.date AND m.username = s.username
WHEN MATCHED THEN UPDATE SET m.duration = s.duration
WHEN NOT MATCHED THEN
INSERT (username, date, time)
VALUES (s.username, s.date, s.time)

非常感谢!

最佳答案

关于sql - 触发更新现有数据或在数据不存在时插入(多行支持),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14934686/

相关文章:

mysql - 如何为每个对话选择最后一条消息?

sql-server - SQL Server 2008 : Why table scaning when another logical condition is satisfied first?

c# - 是否可以锁定一条记录并仍然允许其他用户读取它?

mysql - 如何在 AFTER UPDATE 触发器中引用最近更新的行

amazon-web-services - 手动触发 Lambda 以从 SQS 读取

sql - INSERT INTO 插入一行全是空值

sql - 在 Case 内嵌入 If 语句

sql - 打印动态参数值

sql-server - 错误 'the subreport could not be found at the specified location. Please verify that the subreport has been published and that the name is correct'

google-apps-script - 如何将触发器限制到特定工作表/选项卡?