2016-05-04 10 views
1

私はこのSQL Serverコードを持っています。それ以外のすべては、同じRightsIdUserIdの行を複製します。 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) 
+3

[NOLOCKをどこにでも置くための嫌な習慣](http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/) - これはどこにでも使用することをお勧めしません。反対! –

+0

(NOLOCK)は重複の問題ですか? –

答えて

1

あなたの重複は、おそらく、クエリ内ではなく、テーブル内の既存の行からから来ています。場合によっては、問題は、newid()が常に一意であるため、select distinctは何もしていないということです。

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; 

うーん、私はこれを考えると、おそらくあなたはむしろSELECT DISTINCTよりTOP 1を使用する必要があります:あなたは、クエリを修正することができます、ということ不在。私はどの列が別の列で問題を引き起こすのかは分かりませんが、複数の列に同じ値を挿入しているため、複数行で問題が発生する可能性があります。

+0

複数の行の問題をより正確に診断するために、おそらく彼のスキーマとサンプルデータを参照する必要があります。 –

+1

お問い合わせいただきありがとうございます。 –

0

は、WHERE句をEXISTS、NOTの代わりに(Visual Representation of SQL Joinsを参照してください) "左除く参加" してください。

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 
関連する問題