最初我尝试使用IF / ELSE来完成" UPSERT"并且有人建议我使用MERGE
我MERGE
的问题,看起来我不能使用两个来源。
这是我原创的尝试:
IF ((SELECT COUNT(CAST(StudentuserID AS int)) FROM HL_StudentAttendance WHERE StudentUserID=1)>0)
UPDATE HL_StudentAttendance
SET
CID = CAST('[querystring:CID]' AS int),
CalendarEventID = CAST('[querystring:CEID]' AS int),
StudentUserID = CAST('[StudentUserID]' AS int),
Attendance = '[Attendance]'
ELSE
INSERT INTO HL_StudentAttendance
(CID,CalendarEventID,StudentUserID,Attendance)
VALUES
(CAST('[querystring:CID]' AS int), CAST('[querystring:CEID]' AS int), CAST('[StudentsUserID]' AS int),'[Attendance]')
即使IF语句结果是8
所以8>0
它应该运行我的更新,它总是运行一个插入,不确定我的if / else逻辑是否遗漏了什么。
以下是MERGE
MERGE
HL_StudentAttendance AS target
USING
HL_CourseRegistrations AS source
ON
target.StudentUserID = source.UserID
AND source.
WHEN MATCHED THEN
UPDATE SET
Attendance = '[Attendance]'
WHEN NOT MATCHED THEN
INSERT (CID, CalendarEventID, StudentUserID, Attendance) VALUES ('[querystring:CID]', '[querystring:CEID]', '[UserID]', '[Attendance]')
;
我的问题是我的表HL_CourseEvents
中有数据应该用于获取CalendarEventID
的其他源项,否则MERGE
可以工作,但会在我的{{{}}中插入重复的条目{1}}因为HL_StudentAttendance
任何建议表示赞赏。
更新
以下查询确实有效,但如果在出勤字段上更改了任何内容而不是正确更新,则会插入新记录。我怀疑因为我的更新中的WHERE子句不存在。我尝试添加它导致执行错误
CalendarEventID
查询结果运行两次。如果我继续运行它,它将始终插入更多而不是更新:
MERGE HL_StudentAttendance
USING
(
SELECT cr.CID, ce.CalendarEventID, cr.UserID FROM HL_CourseRegistrations cr
JOIN HL_CalendarEvents ce
ON ce.CID = cr.CID
) tmpTable
ON
HL_StudentAttendance.StudentUserID = tmpTable.UserID
AND HL_StudentAttendance.CalendarEventID = tmpTable.CalendarEventID
WHEN MATCHED THEN
UPDATE
SET
Attendance = 'Attended Late'
WHEN NOT MATCHED THEN
INSERT (CID,CalendarEventID,StudentUserID,Attendance) VALUES ('1','1','1','555')
;
答案 0 :(得分:1)
根据其他信息,请尝试以下操作。我已经将模式和一些数据混合在一起仅用于演示目的,因此您必须了解模式的比较方式。然而,底部的两个例子做了我相信的问题。如果根据用户ID不存在,则第一个插入新记录。第二个标志记录为"参加晚期"如果它存在请注意,对于现实生活,您可能需要多个参数,因为用户可以注册多个课程,因此您也希望传递课程或日历事件ID。如果这让你开始或者你需要额外的东西,请告诉我。
--
-------------------------------------------------
CREATE TABLE [test].[HL_StudentAttendance]
(
[StudentUserID] INT
, [CalendarEventID] INT
, [Attendance] NVARCHAR(250)
, [CID] INT
);
CREATE TABLE [test].[HL_CourseRegistrations]
(
[CID] INT
, [UserID] INT
);
CREATE TABLE [test].[HL_CalendarEvents]
(
[CalendarEventID] INT
, [CID] INT
);
go
--
-------------------------------------------------
INSERT INTO [test].[HL_CourseRegistrations]
([CID]
, [UserId])
VALUES (1,1),
(3,4),
(4,5);
INSERT INTO [test].[HL_CalendarEvents]
([CalendarEventID]
, [CID])
VALUES (1,1);
go
--
-------------------------------------------------
CREATE PROCEDURE [test].[set_attendance] @user INT
AS
BEGIN
MERGE INTO [test].[HL_StudentAttendance] AS [target]
USING (SELECT [cr].[CID]
, [ce].[CalendarEventID]
, [cr].[UserID]
FROM [test].[HL_CourseRegistrations] [cr]
JOIN [test].[HL_CalendarEvents] [ce]
ON [ce].[CID] = [cr].[CID]) AS [source]
ON [target].[StudentUserID] = @user
AND [target].[CalendarEventID] = [source].[CalendarEventID]
WHEN MATCHED THEN
UPDATE SET [Attendance] = 'Attended Late'
WHEN NOT MATCHED BY target THEN
INSERT ([CID]
, [CalendarEventID]
, [StudentUserID]
, [Attendance])
VALUES ('1'
, '1'
, @user
, '555');
END;
go
--
-- inserts a new record
-------------------------------------------------
EXECUTE [test].[set_attendance]
@user=12;
SELECT *
FROM [test].[HL_StudentAttendance];
--
-- marks an existing record as late
-------------------------------------------------
EXECUTE [test].[set_attendance]
@user=12;
SELECT *
FROM [test].[HL_StudentAttendance];