Welcome to Sign in | Help

Re: Oglindire tabela pe servere diferite

  •  11-10-2007, 9:42 PM

    Re: Oglindire tabela pe servere diferite

    Pe server-ul unde este baza de date sursă:

    CREATE DATABASE PseudoSincronizareSursa
    GO

    USE PseudoSincronizareSursa
    GO

    CREATE TABLE Produs
    (
        CodProdus INT PRIMARY KEY,
        DenumireProdus VARCHAR(50) NOT NULL,
        Stare ROWVERSION NOT NULL --ROWVERSION <=> TIMESTAMP
    )
    GO

    CREATE UNIQUE INDEX idx_produs_stare
    ON Produs (Stare)
    GO

    /*
    --Ai posibilitatea sa se defineste un index care sa includa toate campurile
    --care trebuiesc exportate din sursa in destinatie
    CREATE INDEX idx_produs_stare
    ON Produs (Stare,CodProdus,DenumireProdus)
    */

    INSERT INTO Produs (CodProdus,DenumireProdus) VALUES (1,'Mere')
    INSERT INTO Produs (CodProdus,DenumireProdus) VALUES (2,'Portocale')
    INSERT INTO Produs (CodProdus,DenumireProdus) VALUES (3,'Lamai')
    INSERT INTO Produs (CodProdus,DenumireProdus) VALUES (4,'Pere')
    GO

    Pe fiecare server unde există câte o bază de date destinaţie:

    CREATE DATABASE PseudoSincronizareDestinatie
    GO

    USE PseudoSincronizareDestinatie
    GO

    CREATE TABLE Produs
    (
        CodProdus INT PRIMARY KEY,
        DenumireProdus VARCHAR(50) NOT NULL,
        Stare BINARY(8)  NOT NULL
    )
    GO


    EXEC sp_addlinkedserver 
        @server = 'LINK_SQLSERVER_SURSA',
        @srvproduct = '',
        @provider = 'SQLNCLI',
        @datasrc = 'OOSQL\SQLEXPRESS',
        @catalog = 'PseudoSincronizareSursa'
    GO

    --activezi optiunea RPC OUT pentru serverul "linked"
    EXEC master.dbo.sp_serveroption
        @server='LINK_SQLSERVER_SURSA',
        @optname='rpc out',
        @optvalue='true'
    GO

    EXEC sp_addlinkedsrvlogin
        @rmtsrvname = 'LINK_SQLSERVER_SURSA',
        @useself = 'TRUE',
        @locallogin = 'oosql\bgdn'
    GO


    CREATE PROCEDURE spSincronizare
    AS
        DECLARE @tbl TABLE ( CodProdus INT, DenumireProdus VARCHAR(50), Stare BINARY(8) )

        DECLARE @max ROWVERSION
        SET @max = ISNULL( (SELECT MAX(Stare) FROM Produs) , 0x0 )

        INSERT INTO @tbl (CodProdus, DenumireProdus, Stare)
        SELECT CodProdus, DenumireProdus, Stare
        FROM LINK_SQLSERVER_SURSA.PseudoSincronizareSursa.dbo.Produs
        WHERE Stare > @max

        UPDATE Produs
        SET Produs.DenumireProdus = T.DenumireProdus, Produs.Stare = T.Stare
        FROM @tbl AS T
        WHERE Produs.CodProdus = T.CodProdus

        INSERT INTO Produs (CodProdus, DenumireProdus, Stare)
        SELECT CodProdus, DenumireProdus, Stare
        FROM @tbl AS T
        WHERE T.CodProdus NOT IN (SELECT CodProdus FROM Produs)
    GO

     

    În mod asemănător cu exemplul anterior, pentru sincronizare apelezi procedura stocată
    EXEC spSincronizare  


    În continuare, poti adăuga şi modifica date în baza de date sursă:

    INSERT INTO Produs (CodProdus,DenumireProdus) VALUES (5,'Soareci optici')
    UPDATE Produs SET DenumireProdus = 'Ala bala portocala' WHERE CodProdus = 2

    si sa realizezi sincronizarea din nou
    EXEC spSincronizare 


    Observaţii:

    [1] În tabela sursă se defineşte un câmp Stare de tip timestamp / rowversion. Valorile acestui câmp sunt coduri unice generate automat de server crescător (conform BOL). Avantajul acestui tip de date - în acest caz - vine din faptul că în momentul modificării unei înregistrări în baza de date sursă (bd PseudoSincronizareSursa) se modifică automat şi valoarea din câmpul timestamp / rowversion Stare, generându-se un nou cod pentru înregistrarea respectivă. 

    [2] Plecându-se de la valoarea maximă rowversion/timestamp din campul Stare a tabelei destinaţie Produs (bd PseudoSincronizareDestinatie) se pot filtra datele din tabela  sursă Produs (bd PseudoSincronizareSursa). Daca în baza de date sursă se modifică/inserează 100 de înregistrari dintr-un total de 10.000 prin această filtrare, server-ul destinaţie primeşte de server-ul sursă doar 1% din înregistrări (adică 100 de înregistrări) spre deosebire de implementarea anterioară în care server-ul destinaţie primeşte de la serverul sursă toate înregistrarile: 100% (adică 10000). Lucru acesta se poate observa  analizând planurile de execuţie.

    [3] Soluţia se aplică doar pentru inserarea şi modificarea produsele, dar se poate adapta şi  pentru cazul în care se doreşte ştergerea de produse.

    [4] Parţial - doar pentru sincronizarea produselor noi inserate - soluţia poate fi aplicată daca există doar un câmp numeric IDENTITY care nu contine valori nule.

     



     

View Complete Thread
Powered by Community Server (Commercial Edition), by Telligent Systems