I try using the cursor to sort through the source data and make certain changes for each record. Here is the request itself:
DECLARE @ID bigint --id attachments DECLARE @personID BIGINT DECLARE @territoryServiceID BIGINT DECLARE @isAtClosed BIT DECLARE @currentServerDate DATETIME = '2016-01-01 01:10:00.000' --this change GETDATE() DECLARE @BeginDate DATETIME SET @BeginDate = @currentServerDate DECLARE @periodYear INT SET @periodYear = DATEPART(YEAR,@currentServerDate) - 1 DECLARE cur cursor LOCAL STATIC FOR SELECT at.id, at.personID, at.territoryServiceID, ts.isClosing FROM Attachments at INNER JOIN Person p ON p.id = at.personID AND p.parentID IS NULL INNER JOIN TerritoryServices ts ON ts.id = at.territoryServiceID LEFT JOIN Attachments at2 ON at2.personID = at.personID AND at2.parentID = at.id AND at2.attachmentStatusID IN (2,11,12) WHERE at.attachmentStatusID = 1 AND at.causeOfAttachID = 8 AND at.endDate IS NOT NULL AND at2.id IS NULL AND p.id IN (15300000019296419,15300000018501113,15300000014988209,414674754,420940229,409531785) OPEN cur FETCH NEXT FROM cur INTO @ID, @personID, @territoryServiceID, @isAtClosed WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @personID_NVARCHAR NVARCHAR(MAX) SET @personID_NVARCHAR = CONVERT(NVARCHAR(MAX),@personID) PRINT '1 ('+@personID_NVARCHAR+')' IF (@isAtClosed = 1) -- if ter of CA is closing BEGIN -- Insert error into ErrorHandlingCampainOfAttach DECLARE @ErrorDescr NVARCHAR(MAX) SET @ErrorDescr = 'TerId: ' + CONVERT(NVARCHAR(MAX),@territoryServiceID) INSERT INTO [dbo].[ErrorHandlingCampainOfAttach] ([AttachmentsID],[personID],[territoryServiceID],[periodYear],[reasonError],[addDate],[description]) VALUES (@ID, @personID, @territoryServiceID, @periodYear, 1, GETDATE(), @ErrorDescr) END ELSE BEGIN DECLARE @terAt2ID BIGINT DECLARE @isAt2Close BIT = 0 SELECT @isAt2Close = ts.isClosing, @terAt2ID = ts.id FROM Attachments at INNER JOIN TerritoryServices ts ON ts.id = at.territoryServiceID WHERE at.personID = @personID AND at.attachmentStatusID = 2 AND at.endDate IS NULL IF (@isAt2Close = 1) -- if ter of attach is closing BEGIN -- Insert error into ErrorHandlingCampainOfAttach DECLARE @ErrorDescr2 NVARCHAR(MAX) SET @ErrorDescr2 = 'TerAttachId: ' + CONVERT(NVARCHAR(MAX),@terAt2ID) INSERT INTO [dbo].[ErrorHandlingCampainOfAttach] ([AttachmentsID],[personID],[territoryServiceID],[periodYear],[reasonError],[addDate],[description]) VALUES (@ID, @personID, @territoryServiceID, @periodYear, 2, GETDATE(), @ErrorDescr2) END ELSE BEGIN BEGIN TRY BEGIN TRANSACTION TranName -- Search active request DECLARE @ID_zapros BIGINT SELECT @ID_zapros = id FROM Attachments WHERE personID = @personID AND endDate IS NULL AND attachmentStatusID != 2 AND id != @ID IF (@ID_zapros IS NOT NULL) BEGIN -- Canseled request -- Block #1 -- Create cancel for active request INSERT INTO Attachments (personID,orgHealthCareID,personAddressesID,territoryServiceID,attachmentProfileID,doctorID, causeOfAttachID,careAtHome,senderRequestID,senderSystemID,attachmentStatusID,beginDate,endDate,parentID,userID,registratorID, actualAttachmentID,ConflictAttachment,Node,regDate,isMigrated,isDuplicate,oldPersonID,servApplicationID,Num) SELECT at.personID,at.orgHealthCareID,at.personAddressesID,at.territoryServiceID,at.attachmentProfileID, at.doctorID, 8,at.careAtHome,NULL,NULL, 11, @BeginDate, @BeginDate, at.id, at.userID, at.registratorID, at.actualAttachmentID, NULL,NULL,at.regDate,NULL,0,at.oldPersonID,NULL,at.Num FROM Attachments at WHERE at.id = @ID_zapros -- Set endDate for active request UPDATE Attachments SET endDate = @BeginDate WHERE id = @ID_zapros END --Search active attach DECLARE @ID_prikrep BIGINT SELECT @ID_prikrep = id FROM Attachments WHERE personID = @personID AND endDate IS NULL AND attachmentStatusID = 2 IF (@ID_prikrep IS NOT NULL) BEGIN -- Block #2 -- Insert detach INSERT INTO Attachments (personID,orgHealthCareID,personAddressesID,territoryServiceID,attachmentProfileID,doctorID, causeOfAttachID,careAtHome,senderRequestID,senderSystemID,attachmentStatusID,beginDate,endDate,parentID,userID,registratorID, actualAttachmentID,ConflictAttachment,Node,regDate,isMigrated,isDuplicate,oldPersonID,servApplicationID,Num) SELECT at.personID,at.orgHealthCareID,at.personAddressesID,at.territoryServiceID,at.attachmentProfileID, at.doctorID, 8,at.careAtHome,NULL,NULL, 8, @BeginDate, @BeginDate, at.id, at.userID, at.registratorID, at.actualAttachmentID, NULL,NULL,at.regDate,NULL,0,at.oldPersonID,NULL,at.Num FROM Attachments at WHERE at.id = @ID_prikrep --Set endDate for active attach UPDATE Attachments SET endDate = @BeginDate WHERE id = @ID_prikrep END -- Attach CA INSERT INTO Attachments (personID,orgHealthCareID,personAddressesID,territoryServiceID,attachmentProfileID,doctorID, causeOfAttachID,careAtHome,senderRequestID,senderSystemID,attachmentStatusID,beginDate,endDate,parentID,userID,registratorID, actualAttachmentID,ConflictAttachment,Node,regDate,isMigrated,isDuplicate,oldPersonID,servApplicationID,Num) SELECT at.personID,at.orgHealthCareID,at.personAddressesID,at.territoryServiceID,at.attachmentProfileID, at.doctorID, 8,at.careAtHome,NULL,NULL, 2, @BeginDate, NULL, at.id, at.userID, at.registratorID, at.actualAttachmentID, NULL,NULL,at.regDate,NULL,0,at.oldPersonID,NULL,at.Num FROM Attachments at WHERE at.id = @ID COMMIT TRANSACTION TranName END TRY BEGIN CATCH ROLLBACK TRANSACTION TranName -- Insert error into ErrorHandlingCampainOfAttach INSERT INTO [dbo].[ErrorHandlingCampainOfAttach] ([AttachmentsID],[personID],[territoryServiceID],[periodYear],[reasonError],[addDate],[description]) VALUES (@ID, @personID, @territoryServiceID, @periodYear, 3, GETDATE(),ERROR_MESSAGE()) END CATCH END END FETCH NEXT FROM cur INTO @ID, @personID, @territoryServiceID, @isAtClosed END CLOSE cur DEALLOCATE cur The query for the cursor returns 6 lines (6 are selected for the example), that is, all IDs are unique, nothing is duplicated. Further, depending on certain conditions, certain actions are carried out, please pay attention to two blocks of actions (called Block # 1 and Block # 2 in the comments), they behave strangely.
After fulfilling a request for some (it is also important here, not always on the same record, it happens then on one then another, or even two) records are backed up with data lines, that is, two lines are inserted that have all the data except the auto-increment identifier is repeated! And if you roll back the actions and try only on this record on one (that is, run a cycle for one record) everything ends perfectly! These are the evil electrical forces. It is not clear why this is happening, tell someone what is wrong, or in which direction to look for a solution?
PS Triggers to insert data on the table Attachments no. Lines are always inserted after all actions, that is, let's say the first condition is fulfilled, line 1 is inserted, then line 2 is inserted by the second condition, then line 3, and if the line is doubled, then it is inserted most recently, that is, after line 3 line 4 is identical to line 1 (or line 2 when as)





FOR UPDATEto the cursor query. But I never encountered MS SQL, so just a guess - Mike