验证值是否在插入行之前存在

时间:2018-09-28 17:57:29

标签: sql sql-server tsql

我有一个查询,我向其中发送一个TableType,其中包含列EmpKeyTaskId,例如:

  @AssignNotificationTableType [dbo].[udf_TaskNotification] READONLY

INSERT INTO [TaskNotification] ([TaskId], [EmpKey])
    SELECT
        [ANT].[TaskId], [E].[EmpKey]
    FROM 
        @AssignNotificationTableType AS [ANT]
    INNER JOIN 
        [Employee] AS [E] ON [ANT].[EmpGuid] = [E].[EmpGuid]

所以我的桌子看起来像这样:

+--------------------------------------+--------------------------------------+--------+
|          TaskNotificationId          |                TaskId                | EmpKey |
+--------------------------------------+--------------------------------------+--------+

| EEE3D3F8-F190-E811-841F-C81F66DACA6A | D0440DEB-404C-4006-870F-E95BFFA840E0 |     44 |
| EFE3D3F8-F190-E811-841F-C81F66DACA6A | D0440DEB-404C-4006-870F-E95BFFA840E0 |     49 |
+--------------------------------------+--------------------------------------+--------+

您会看到两个项目具有相同的TaskId但具有不同的Empkey,所以假设如果我再次发送相同的TaskId D0440DEB-404C-4006-870F-E95BFFA840E0,则只在EmpKey时才插入行该TaskId中不存在

所以,如果我发送类似的内容:

+--+--------------------------------------+--------+
|  |                TaskId                | EmpKey |
+--+--------------------------------------+--------+
|  | D0440DEB-404C-4006-870F-E95BFFA840E0 |     44 |
|  | D0440DEB-404C-4006-870F-E95BFFA840E0 |     49 |
|  | D0440DEB-404C-4006-870F-E95BFFA840E0 |     54 |
+--+--------------------------------------+--------+

它只会插入最后一行,因为EmpKey中不存在TaskId 54

我尝试在WHERE子句中使用NOT IN作为

INSERT INTO [TaskNotification] ([TaskId], [EmpKey])
    SELECT
        [ANT].[TaskId], [E].[EmpKey]
    FROM 
        @AssignNotificationTableType AS [ANT]
    INNER JOIN 
        [Employee] AS [E] ON [ANT].[EmpGuid] = [E].[EmpGuid]
    WHERE 
        [E].[EmpKey] NOT IN (SELECT EmpKey
                             FROM [TaskNotification]
                             WHERE TaskId = (SELECT TaskId 
                                             FROM @AssignNotificationTableType))

但是当我运行它时,它只是不插入任何东西。我究竟做错了什么?问候

1 个答案:

答案 0 :(得分:4)

将目标表作为左连接添加到select语句:

INSERT INTO [TaskNotification]
(
     [TaskId]
    , [EmpKey]
)
 SELECT
       [ANT].[TaskId]
     , [E].[EmpKey]
       FROM @AssignNotificationTableType AS [ANT]
           INNER JOIN [Employee] AS [E] ON [ANT].[EmpGuid] = [E].[EmpGuid]
           LEFT JOIN [TaskNotification] AS [TN] ON [TN].[TaskId] = [ANT].[TaskId]
               AND [TN].[EmpKey] = [E].[EmpKey]
       WHERE [TN].[PK] IS NULL -- PK stands for the primary key column 
       -- (or first column in of a multiple columns pk)

但是请注意,在多线程环境中,这样的查询可能会失败-有关更多信息,请阅读this SO post并链接到Dan Guzman的博客。