Trigger per replicare da un db a un altro ............

venerdì 20 giugno 2008 - 01.01

cristian75 Profilo | Newbie

Ciao a tutti,
vi espongo subito il mio quesito, supponendo di avere 2 Database sullo stesso server, ho la necessità di replicare alcune colonne di una tabella del DbA nel DbB, io pensavo di utilizzare un trigger nella tabella del DbA che ad ogni inserimento, aggiornamento e cancellazione vada a modificare la tabella nel DbB, tipo:
-------------------------------------
create trigger CopiaRiga
on TabellaA
after insert, Update, Delete
as
begin

Declare @dato1 int
Declare @dato2 Varchar(50)

------------------------------------

e QUI arrivano le note dolenti, non capisco come fare ad assegnnare alle variabili locali i valori appena inseriti, modificati, cancellati ??? Tipo:

SET @dato1 = (SELECT dato1 FROM tabellaA) APPENA SCRITTO
SET @dato2 = (SELECT dato2 FROM tabellaB) APPENA SCRITTO

e poi, risolto questo proseguirei il tutto con un

USE DbB

INSETR INTO TabellaB (Dato1, Dato2)
VALUES (@dato1, @dato2)

Non so se forse questo metodo è un po troppo "sempliciotto"

qualcuno riece ad indicarmi il sentiero da percorrere per uscire da questo inghippo ??

Grazie



Dainesi Profilo | Senior Member

Perchè non risolvi tutto con una bella sincronizzazione transazionale ?

lbenaglia Profilo | Guru

>vi espongo subito il mio quesito, supponendo di avere 2 Database
>sullo stesso server, ho la necessità di replicare alcune colonne
>di una tabella del DbA nel DbB, io pensavo di utilizzare un trigger
>nella tabella del DbA che ad ogni inserimento, aggiornamento
>e cancellazione vada a modificare la tabella nel DbB

Ciao Cristian,

Ritieni che sia fondamentale allineare in modo sincrono le due tabelle oppure puoi permetterti di allinearle in modalità asincrona?

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

cristian75 Profilo | Newbie

Sinceramente non conosco la differenze tra l'allineamento Sincron e l'allineamento asincrono, e nemmeno i pro e i contro di una tabella transazionale, vi descrivo la situazione in modo tale che possiate avere una visione d'insieme tale da aiutarmi nella scelta, io ho 2 sistemi che si occupano del controllo Accessi di un palazzo il sistema A per 1° e 2° piano e il B il 3° piano i due sistemi sono indipendente e comunicano con le apparecchiature in campo.
entrambi i istemi si basano su un Db MSSQL.
Attualmente un che accede al palazzo deve essere abilitato sia sul sistema A che sul sistema B utilizzando 2 interfaccee utente diverse, il mio obbiettivo e fare in modo che quando un utente viene abilitato sul sistema A vega abilitato automaticamente anche sul B .
Quindi qando vado a scrivere il nuovo utente nella tabella ANAGRAFICA_SISTEMA_A un trigger preleva i dati appena scritti e dopo diversi passaggi per stabilire le dovute confersioni e il dovuto template abilitativo, scrive nella tabella IMPORTAZIONE_SISTEM_B, in questa tabella oltre i dati relativi all'utente ho anche scritto se devo : INSERIRE o MODIFICARE, l'utente settando il campo FUNZIONE della tabella, a questo punto una routine che verifica ogni 5 secondi vedrà la nuova riga leggerà il tipo di funzione abbinata ad essa e inserirà l'utente secondo le regole della funzione stabilita, quando il nuovo utente srarà stato scritto nella tabella ANAGRAFICA_SISTEM_B cancellera la nuova riga nell tabella IMPORTAZIONE_SISTEM_B.

Detto fatto, tutto funziona già bene, se scrivo nella tabella IMPORTAZIONE_SISTEM_B a manina, devo solamente raffinare il sistema di trigger automatico ..... cosa mi consigliate di fare ??

Spero si essere stato chiaro ... nella esposizione ....

Grazie mille

lbenaglia Profilo | Guru

>Sinceramente non conosco la differenze tra l'allineamento Sincron
>e l'allineamento asincrono, e nemmeno i pro e i contro di una
>tabella transazionale

Un allineamento sincrono (in tempo reale) può essere eseguito via triggers, ma quando è possibile evitane l'utilizzo è meglio, dato che prolungano la durata delle transazioni, di conseguenza dei locks diminuendo la scalabilità dell'applicazione.

Se invece puoi permetterti di allineare la seconda tabella ogni x minuti, ore, giorni (modalità asincrona), questa operazione può essere svolta schedulando un JOB che esegue gli aggiornamenti del caso, senza "rallentare" l'utilizzo del db sorgente.

Ora, quale delle due strade puoi permetterti di utilizzare?

>Grazie mille
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

Dainesi Profilo | Senior Member

La domanda sorge spontanea ... ma se sei tu che inserisci un nuovo utente significa che utilizzi una maschera, un applicazione che manipola i dati. E allora perché non demandi a quest'applicazione la doppia scrittura ?

cristian75 Profilo | Newbie

Decisamente l'unica strada da percorrere in questo caso e quella della modalità sincrona dato che nel momento in cui un visitatore viene mandato in campo il tempo di latenza delle autorizzazioni deve essere indubbiamente il minore possibile, in modo da permettere all'utente di accedere nelle aree appena abilitate.

Ciao

cristian75 Profilo | Newbie

>La domanda sorge spontanea ... ma se sei tu che inserisci un
>nuovo utente significa che utilizzi una maschera, un applicazione
>che manipola i dati. E allora perché non demandi a quest'applicazione
>la doppia scrittura ?

Semplice, il sistema A " Quello attualmente utilizzato per definire gli utenti " è un sistema che non è possibile modificare, è scritto in delphi e non è ne possibile ne convegnente modificare, dato che andrà in disuso in breve tempo, il sistema B è la naturale evulizione di quello a che andrà a sostituire, quindi ci siamo concentrati sulla gestione delle funzioni d'importazione su un sistema appena nato e quindi ampliabile. Tieni presente che sul sistema nuovo non si è creata una routine d'importazione dedicata al sistema vecchio, ma si è scelto di creare una routine di importazione con delle regole ben precise, slegata dai fattori di criptazione dei dati effettivamente contenuti nel db ..... in modo tale che il sistema sia compatibile con qualsiasi altro sistema che può andare a scrivere sulla tabella IMPORTA_SISTEMA_B senza preoccuparsi di nient'altro, ci pensa la routine a mettere a posto le cose.

Ciao

lbenaglia Profilo | Guru

>Decisamente l'unica strada da percorrere in questo caso e quella
>della modalità sincrona
Va bene, allora non ci sono scappatoie

Dato che non hai postato i comandi DDL delle tabelle, mi limiterò a fornirti un esempio su due tabelle fittizie: starà a te capirne il funzionamento in modo da adattarlo alle tue esigenze, OK?

USE tempdb; CREATE TABLE dbo.Students1( StudentID int NOT NULL IDENTITY PRIMARY KEY, FirstName varchar(10) NOT NULL, LastName varchar(10) NOT NULL ); CREATE TABLE dbo.Students2( StudentID int NOT NULL IDENTITY PRIMARY KEY, FirstName varchar(10) NOT NULL, LastName varchar(10) NOT NULL ); GO CREATE TRIGGER dbo.trI_AlignStudents ON dbo.Students1 FOR INSERT AS IF NOT EXISTS( SELECT * FROM INSERTED AS I JOIN dbo.Students2 AS S2 ON I.StudentID = S2.StudentID ) BEGIN INSERT dbo.Students2(FirstName, LastName) SELECT FirstName, LastName FROM INSERTED END GO CREATE TRIGGER dbo.trD_AlignStudents ON dbo.Students1 FOR DELETE AS DELETE S2 FROM dbo.Students2 AS S2 JOIN DELETED AS D ON D.StudentID = S2.StudentID GO CREATE TRIGGER dbo.trU_AlignStudents ON dbo.Students1 FOR UPDATE AS UPDATE S2 SET FirstName = I.FirstName, LastName = I.LastName FROM INSERTED AS I JOIN dbo.Students2 AS S2 ON I.StudentID = S2.StudentID GO /* Inserimento singolo */ INSERT dbo.Students1 VALUES ('Lorenzo', 'Benaglia'); /* Inserimento multiplo */ INSERT dbo.Students1 SELECT 'Luca', 'Bianchi' UNION ALL SELECT 'Andrea', 'Montanari' UNION ALL SELECT 'Gianluca', 'Hotz'; SELECT * FROM dbo.Students2; /* Output: StudentID FirstName LastName ----------- ---------- ---------- 1 Lorenzo Benaglia 2 Gianluca Hotz 3 Andrea Montanari 4 Luca Bianchi (4 row(s) affected) */ /* Aggiornamento singolo */ UPDATE dbo.Students1 SET FirstName = 'Alessandro', LastName = 'Alpi' WHERE StudentID = 2; /* Aggiornamento multiplo */ UPDATE dbo.Students1 SET FirstName = 'Davide', LastName = 'Mauri' WHERE StudentID IN(3, 4); SELECT * FROM dbo.Students2; /* Output: StudentID FirstName LastName ----------- ---------- ---------- 1 Lorenzo Benaglia 2 Alessandro Alpi 3 Davide Mauri 4 Davide Mauri (4 row(s) affected) */ /* Eliminazione singola */ DELETE dbo.Students1 WHERE StudentID = 4; /* Eliminazione multipla */ DELETE dbo.Students1 WHERE StudentID IN(2, 3); SELECT * FROM dbo.Students2; /* Output: StudentID FirstName LastName ----------- ---------- ---------- 1 Lorenzo Benaglia (1 row(s) affected) */ DROP TABLE dbo.Students1, dbo.Students2;

Nel mio esempio le tabelle appartengono nel medesimo database; nel tuo caso dovrai ricorrere al three-part name (database.schema.tabella).

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

cristian75 Profilo | Newbie

Grazie mille Lorenzo l'esempio è chiarissimo e si avvicina parecchio a quello che stavo progettando, a differenza che io cercavo di usare

USE DATABASEB per cambiare database .... e questo non si può fare

invece con [db].[dbo].[tabella] lo fa lo fa !!!

c'è una parte che non capisco saresti così gentile da spiegarmi che cosa fa con questo IF NOT EXIST ??

------------------------------------------------

>IF NOT EXISTS(
> SELECT *
> FROM INSERTED AS I
> JOIN dbo.Students2 AS S2
> ON I.StudentID = S2.StudentID
>)
-----------------------------------------------

Grazie mille mi sei stato di molto aiuto

lbenaglia Profilo | Guru

>c'è una parte che non capisco saresti così gentile da spiegarmi
>che cosa fa con questo IF NOT EXIST ??
>
>------------------------------------------------
>
>>IF NOT EXISTS(
>> SELECT *
>> FROM INSERTED AS I
>> JOIN dbo.Students2 AS S2
>> ON I.StudentID = S2.StudentID
>>)
>-----------------------------------------------

Prima di eseguire l'inserimento, verifico che non esista già uno studente con quell'ID.
Teoricamente non dovrebbe esistere, ma nessuno può garantirci che qualcun altro non abbia "pastrugnato" con la seconda tabella...

>Grazie mille mi sei stato di molto aiuto
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

cristian75 Profilo | Newbie

Chiarissimo Grazie .

Alla prossima ...

Ciao
Cristian
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5