Sql server TSQL与多个源合并

Sql server TSQL与多个源合并,sql-server,tsql,Sql Server,Tsql,最初我尝试使用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), Calen

最初我尝试使用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
它应该运行我的更新,但它总是运行insert,不确定我的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\u CourseeEvents
中有数据,应该用来获取一个额外的源项,即
CalendarEventID
,否则
MERGE
会起作用,但会将重复条目插入我的
HL\u StudentAttendance
,因为
CalendarEventID
没有参数

如有任何建议,我们将不胜感激

更新

以下查询确实有效,但如果考勤字段中有任何更改而不是正确更新,则会插入新记录。我怀疑是因为我的更新中的WHERE子句不存在。我尝试添加它以获得执行错误

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')
;
查询结果运行两次。如果我继续运行它,它将始终插入更多内容,而不是更新:

ID  CID CalendarEventID StudentUserID Attendance
1   1   1               1             Attended Late
2   1   1               1             Attended Late
3   1   1               1             Attended Late
4   1   1               1             Attended Late
5   1   1               1             Attended Late
6   1   1               1             555
7   1   1               1             555
8   1   1               1             555
9   1   1               1             555

根据其他信息,请尝试以下操作。我将一个模式和一些数据拼凑在一起,只是为了演示,所以您必须查看您的模式的比较情况。然而,下面的两个例子符合你的要求,我相信。第一个根据用户id插入一条新记录(如果不存在)。第二个根据用户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]; 

谢谢你的回复。
考勤设置
是用户定义的手动过程。我的问题是,我无法在此查询中指定要更新的
用户ID
。当我第一次运行该查询时,数据匹配中存在问题,它插入了5条记录。因为我有5个学生,这是有道理的。我再次运行它,它更新了我的1条记录,然后在应该更新的位置插入5条新记录,而不是此时插入。啊哈!假设您在一个过程中使用它,那么您将使用类似于我在merge()上的演示文稿中所示的内容,使用参数(使用(value(@flower,@color))作为源([flower],[color]),来实现过程[presentation].[merge]。午餐刚到我们办公室。如果你还需要提示,我可以更新。我已经更新了一个结果集,以防它有帮助。如果你有一个很好的例子,对不起,凯瑟琳,我把我的结果放在你的答案里了,我的错误是想把它加到我的问题里。我无法撤消,但您可能可以删除它。