Trigger per 'replica' tabella DB SQL

lunedì 08 ottobre 2007 - 17.16

Fantazma Profilo | Junior Member

Salve
ammetto subito che con SQL con non un drago...
Mi trovo in questa situazione: Ho su un server due DB, chiamiamoli dbA e dbB. Per semplicità entrambi hanno una sola tabella 'Articoli' che contiene due soli campi 'Codice' e 'Articolo'. Ora vorrei che ad ogni inserimento, modifica o cancellazione sul dbA tutte le azioni vengano replicate sul dbB. Ho pensato ai trigger e sono arrivato a questi:


Per l'insert e l'update
USE [dbA] GO /****** Oggetto: Trigger [dbo].[trArticoli] Data script: 10/08/2007 18:10:13 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER [dbo].[trArticoli] ON [dbo].[Articoli] FOR INSERT, UPDATE AS INSERT dbB.Articoli SELECT * FROM INSERTED UPDATE dbB.Articoli SELECT * FROM UPDATED


Per il Delete
USE [dbA] GO /****** Oggetto: Trigger [dbo].[t_Articoli_DU] Data script: 10/08/2007 18:11:15 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER [dbo].[t_Articoli_DU] ON [dbo].[Articoli] FOR DELETE AS DELETE A FROM dbB.Articoli A INNER JOIN DELETED D ON A.Codice = D.Codice


Così, a naso, dovrebbero andare, ma in realtà ottengo per ogni operazione su dbA il seguente errore:

Messaggio 208, livello 16, stato 1, procedura trArticoli, riga 6
Il nome di oggetto 'dbB.Articoli' non è valido.

Dove sto sbagliando???
Grazie infinite!!!

alx_81 Profilo | Guru

>Salve
Ciao!

>ammetto subito che con SQL con non un drago...
>Mi trovo in questa situazione: Ho su un server due DB, chiamiamoli
>dbA e dbB. Per semplicità entrambi hanno una sola tabella 'Articoli'
>che contiene due soli campi 'Codice' e 'Articolo'. Ora vorrei
>che ad ogni inserimento, modifica o cancellazione sul dbA tutte
>le azioni vengano replicate sul dbB. Ho pensato ai trigger
>
>Così, a naso, dovrebbero andare, ma in realtà ottengo per ogni
>operazione su dbA il seguente errore:
>
>Messaggio 208, livello 16, stato 1, procedura trArticoli, riga
>6
>Il nome di oggetto 'dbB.Articoli' non è valido.
>
>Dove sto sbagliando???
devi mettere il nome completo, ad esempio dbB.dbo.Articoli. dbo è il cosiddetto OWNER.. e non puoi ometterlo a meno che non utilizzi la nomenclatura dbB..Articoli. Anche nell'ultimo caso, dovrebbe funzionare.

Mi permetto però di consigliarti la strada delle stored procedure.. non sono un grande fan dei trigger, a volte possono crearti più problemi che altro. Ma ovviamente è una mia opinione. Diciamo che non sono nemmeno troppo visibili e non sempre ti ricordi di averne scritti per alcune tabelle . Nel caso in cui tu voglia cambiare filosofia, puoi scrivere stored procedure che, oltre che inserire nella tabella locale inseriscono anche sulla tabella dell'altro DB, similarmente a come fai sui trigger.. Comunque, con la naming che ti ho indicato dovrebbe funzionare tutto..

>Grazie infinite!!!
di nulla!
Alx81 =)

http://blogs.dotnethell.it/suxstellino

Fantazma Profilo | Junior Member

Ciao
ti ringrazio infinitamente per la dritta... funziona benissimo.
Per quanto riguarda le stored l'idea a dir la verità non l'avevo neanche presa in considerazione... perchè non m'era venuta in mente!!!
Però i trigger in questo caso tornano meglio perchè è solo un piccolo DB e tutte le tabelle devono avere questo trigger di "replica"... quindi il discorso si fa semplice.
Però ho un'altra domanda perchè ovviamente la mia "vasta conoscenza" del T-SQL ha mostrato i suoi limiti.
Nel trigger di inserimento ho un problema ovviamente perchè uno dei campi (nell'esempio il campo 'Counter') è impostato come chiave primaria (identity) con autoincremento. Quindi l'SQL giustamente non ne vuole sapere di inserire un valore in un campo che lui vorrebbe calcolare con le sue manine. Dovrei prendere campo per campo... ma non mi funziona. Ecco quello che avrei scritto:

USE [dbA] GO /****** Oggetto: Trigger [dbo].[trArticoli] Data script: 10/08/2007 18:10:13 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER [dbo].[InsTable] ON [dbo].[Articoli] FOR INSERT AS INSERT dbB.dbo.Articoli VALUES (select articolo FROM dbb.dbo.Articoli S JOIN INSERTED I ON s.Counter = I.Counter)

Mi rendo conto dello sforzo di fantasia da fare per dare una giustificazione al mio codice...

Hai qualche dritta anche per questo problema??? (...che in teoria dovrebbe essere l'ultimo, poi abbandono i trigger e mi ritiro a vita privata con vb.net)

Ciao e grazie ancora infinite

alx_81 Profilo | Guru

>Nel trigger di inserimento ho un problema ovviamente perchè uno
>dei campi (nell'esempio il campo 'Counter') è impostato come
>chiave primaria (identity) con autoincremento. Quindi l'SQL giustamente
>non ne vuole sapere di inserire un valore in un campo che lui
>vorrebbe calcolare con le sue manine.
>Mi rendo conto dello sforzo di fantasia da fare per dare una
>giustificazione al mio codice...
>
>Hai qualche dritta anche per questo problema???
Allora, c'è la possibilità di forzare l'inserimento di record con identity.. ma è un pochino pericoloso..
Ti illustro il problema.
Pensa che sul dbA ci sia una tabella che ha 100 record, da 1 a 100 e che sul dbB ce ne sia una con 0 record.
Ora, tu forzi l'inserimento da A a B e ti ritrovi nella situazione in cui la tabella su dbA ha 100 record da 1 a 100 e la tabella su dbB ha 100 record da 1 a 100. Se un utente cerca di inserire nella tabella di dbB un record, otterrà un errore. Poichè l'id autoincrementante non è stato portato a 101 ma è rimasto al suo valore prima dell'inserimento (probabilmente a 1 e 1 esiste già). Di conseguenza il disallineamento non ti consente una buona gestione del problema, anzi, ti provoca più che altro confusione e ulteriori problemi. Se però non ti interessa di avere gli stessi ID, allora ti consiglio di fare la insert di tutti i campi tranne il contatore. E così non avrai problemi di sorta. Alla fine avrai le due tabelle con gli stessi record ma con un contatore non necessariamente uguale.

>(...che in teoria
>dovrebbe essere l'ultimo, poi abbandono i trigger e mi ritiro
>a vita privata con vb.net)
quindi molli il database e ti porti a sviluppare? non provi nemmeno a scrivere qualche stored procedure in T-SQL???


>
>Ciao e grazie ancora infinite

Alx81 =)

http://blogs.dotnethell.it/suxstellino

Fantazma Profilo | Junior Member

...come sempre preciso, puntuale ed esaustivo. Dato che avere lo stesso indice non è importante posso vivere felice e tranquillo inserendo campo per campo.

>>(...che in teoria
>>dovrebbe essere l'ultimo, poi abbandono i trigger e mi ritiro
>>a vita privata con vb.net)
>quindi molli il database e ti porti a sviluppare? non provi nemmeno
>a scrivere qualche stored procedure in T-SQL???

In verità non mi sono mai impegnato più di tanto nello studio dell'SQL (lo avresti mai detto???) mentre con la piattaforma net per necessità ho dovuto impegnarmi... ma non si sa mai, il giorno che divento ricco e avrò centinaia e centinaia di gente che lavora al posto mio, per diletto mi metterò a studiare l'SQL (in realtà se quel giorno arriverà mai avranno inventato db con interfaccia vocale e richieste standard... )

Ciao e grazie ancora!!!

alx_81 Profilo | Guru

>...come sempre preciso, puntuale ed esaustivo. Dato che avere
>lo stesso indice non è importante posso vivere felice e tranquillo
>inserendo campo per campo.
Non ti seguo.. basta che nella select non compaia il contatore e che nell'elenco dei campi ci siano tutti quelli che ti servono escluso il contatore..
Alx81 =)

http://blogs.dotnethell.it/suxstellino

Fantazma Profilo | Junior Member

>Non ti seguo.. basta che nella select non compaia il contatore
>e che nell'elenco dei campi ci siano tutti quelli che ti servono
>escluso il contatore..

...ovviamente era quello che volevo dire...
Va beh... forse è meglio che mi metta a leggere qualcosa anche prima di diventare ricco... almeno per riuscire a dire quello che voglio
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-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5