我有这个SQL Server代码。除了重复具有相同RightsId
和UserId
的行外,一切正常。 where not exists
子句不起作用。
任何帮助表示赞赏。
INSERT INTO dbo.UserAccessRights (Id, UserId, RightType, RightsId, CreatedOn, CreatedBy)
SELECT DISTINCT
NEWID(),
@changedUserId,
N'Process ' + @rightsTypeSuffix,
ptm.ProcessInstance_id,
getdate(),
@loggedInUserId
FROM
dbo.ProcessTeamMembers ptm WITH (NOLOCK)
INNER JOIN
dbo.Users u WITH (NOLOCK) ON ptm.TeamMemberProfile_id = u.ProfileID
AND u.Id = @changedUserId
AND ptm.TenantId = @tenantId
INNER JOIN
dbo.ProcessInstances p_i WITH (NOLOCK) ON p_i.Id = ptm.ProcessInstance_id
AND p_i.DeletedOn IS NULL
WHERE
NOT EXISTS (SELECT *
FROM UserAccessRights uar WITH (NOLOCK)
WHERE uar.UserId = @changedUserId
AND uar.RightsId = ptm.ProcessInstance_id)
答案 0 :(得分:1)
您的重复项可能来自查询,而不是来自表中的现有行。可能的问题是select distinct
没有做任何事情 - 因为newid()
始终是唯一的。
我的建议是将id
列更改为默认值newid()
。然后您不需要插入它,select distinct
将起作用。如果没有,您可以修复查询:
INSERT INTO dbo.UserAccessRights (Id, UserId, RightType, RightsId, CreatedOn, CreatedBy)
SELECT DISTINCT NEWID(), @changedUserId, N'Process ' + @rightsTypeSuffix,
ProcessInstance_id, getdate(), @loggedInUserId
FROM (SELECT DISTINCT ptm.ProcessInstance_id
FROM dbo.ProcessTeamMembers ptm WITH (NOLOCK) INNER JOIN
dbo.Users u WITH (NOLOCK)
ON ptm.TeamMemberProfile_id = u.ProfileID AND
u.Id = @changedUserId AND
ptm.TenantId = @tenantId INNER JOIN
dbo.ProcessInstances p_i WITH (NOLOCK)
ON p_i.Id = ptm.ProcessInstance_id AND
p_i.DeletedOn IS NULL
WHERE NOT EXISTS (SELECT 1
FROM UserAccessRights uar WITH (NOLOCK)
WHERE uar.UserId = @changedUserId AND
uar.RightsId = ptm.ProcessInstance_id
)
) t;
嗯,正如我想的那样,也许你应该使用TOP 1
而不是SELECT DISTINCT
。我不确定哪些列导致了distinct上的问题,但是您在许多列中插入了相同的值,因此多行可能会导致问题。
答案 1 :(得分:0)
尝试"左排除加入" (参见Visual Representation of SQL Joins)而不是WHERE NOT EXISTS子句。
INSERT INTO dbo.UserAccessRights (Id, UserId, RightType, RightsId, CreatedOn, CreatedBy)
SELECT DISTINCT
NEWID(),
@changedUserId,
N'Process ' + @rightsTypeSuffix,
ptm.ProcessInstance_id,
getdate(),
@loggedInUserId
FROM
dbo.ProcessTeamMembers ptm
INNER JOIN
dbo.Users u ON ptm.TeamMemberProfile_id = u.ProfileID
AND u.Id = @changedUserId
AND ptm.TenantId = @tenantId
INNER JOIN
dbo.ProcessInstances p_i ON p_i.Id = ptm.ProcessInstance_id
AND p_i.DeletedOn IS NULL
LEFT JOIN UserAccessRights uar
ON uar.UserId = u.Id
AND uar.RightsId = ptm.ProcessInstance_id
WHERE
uar.Id IS NULL -- Replace with the actual pkey on UserAccessRights if not Id