Avatar billede Motjida Novice
07. februar 2018 - 19:37 Der er 4 kommentarer og
1 løsning

Replikerings problemer med MERGE statements

Hej Eksperter,

Jeg har et problem med MERGE statements i SQL Server. Jeg to databaser på hver sin server, Begge databaser har en identisk tabel (Test_Schedule i eksemplet herunder). Jeg vil lave et check på hver side, der hvert minut sammenligner begge tabeller og indsætter, opdaterer eller sletter data efter behov.

Dvs. hvis et ID sidst er blevet opdateret på Server1, så skal det opdateres på Server2 og omvendt. Hvis et ID er sidst blevet tilføjet på Server1, så skal det indsættes på Server2 og omvendt. Hvis et ID sidst er blevet slettet fra Server1, så skal det slettes på Server2 og omvendt.

Eksempel koden herunder køres automatisk hvert minut på begge servere, og virker fint til at indsætte og opdatere data, men jeg kan ikke få sletninger til at virke ordentligt da koden i stedet ser det som om at data'en mangler på den ene side, og derfor indsætter det i stedet for at slette det på den anden side.

Hvad er den bedste måde at overkomme det her problem på?

Eksempel kode:

    DECLARE
        @dbDateTime datetime
   
    SET @dbDateTime = DATEADD(HOUR, -24, GETDATE());

    WITH Test_Schedule_CTE (ScheduleID, Section, [Day], StartTime, EndTime, dbDateTime)
    AS 
    ( 
        SELECT
            ScheduleID,
            Section,
            [Day],
            StartTime,
            EndTime,
            dbDateTime
        FROM dbo.Test_Schedule ts
    )
    MERGE Test_Schedule_CTE AS TARGET
    USING (
        SELECT
            ScheduleID,
            Section,
            [Day],
            StartTime,
            EndTime,
            dbDateTime
        FROM [REMOTE].Database.dbo.Test_Schedule ts
        WHERE 1 = 1
                AND dbDateTime >= @dbDateTime
            ) AS SOURCE
        ON (
            TARGET.ScheduleID = SOURCE.ScheduleID
        )
    WHEN MATCHED AND SOURCE.dbDateTime > TARGET.dbDateTime THEN
        UPDATE
        SET TARGET.Section = SOURCE.Section,
            TARGET.[Day] = SOURCE.[Day],
            TARGET.StartTime = SOURCE.StartTime,
            TARGET.EndTime = SOURCE.EndTime,
            TARGET.dbDateTime = SOURCE.dbDateTime
    WHEN NOT MATCHED BY TARGET THEN
    INSERT
        VALUES (
            SOURCE.ScheduleID,
            SOURCE.Section,
            SOURCE.[Day],
            SOURCE.StartTime,
            SOURCE.EndTime,
            SOURCE.dbDateTime
        );
Avatar billede Motjida Novice
08. februar 2018 - 10:39 #1
Jeg kan tilføje et status flag til tabellen og i stedet for at slette data, give det et 'D' flag. Men jeg ville foretrække hvis data'ene blev slettet i stedet for bare at blive gemt.
Avatar billede Slettet bruger
08. februar 2018 - 13:18 #2
Istedet for at sætte vil jeg klart sætte et flag om din række mangler fra den ene side. Hvis den så mangler og sætter et flag som fx IsDeleted = 1, så lav et delete statement bagefter som sletter alt hvor isdeleted = 1.
Avatar billede Slettet bruger
08. februar 2018 - 13:18 #3
Og der skulle stå istedet for at slette*
Avatar billede Slettet bruger
08. februar 2018 - 13:19 #4
Man kan nemlig ikke lave delete i et merge statement.
Avatar billede Slettet bruger
08. februar 2018 - 13:20 #5
Og det passer ikke helt det jeg skrev til sidst.  se ex. her

WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%'
    THEN DELETE
OUTPUT $action, inserted.*, deleted.*;
ROLLBACK TRAN;

https://technet.microsoft.com/en-us/library/bb522522%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396

Men jeg vil helt klart bare sætte et update flag, og så slette det bagefter hvis det er
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester