SSIS : controllo per prevenire inserimento record duplicati

martedì 06 gennaio 2009 - 11.08

the_driver Profilo | Senior Member

Ciao a tutti ,

avrei bisgono di sapere come faccio a controllare che un determinato record che sto inserendo non sia già presente. Ho notato (ovviamente) che , ad ogni modifica del project, rieseguento l'elaborato per verificare i cambiamenti,mi inserisce in append gli stessi record.

Ora, mi chiedo:

- Come posso verificare il funzionamente del mio progetto,dopo ogni mia modifica,senza inserire dei doppioni?
- in generale,c'è un metodo automatizzato ho dovrei , attraverso TSQL, fare dei controlli prima di una qualsiasi INSERT?
-viceversa,nei DATA FLOW, come mi devo comportare?

Grazie

alx_81 Profilo | Guru

>Ciao a tutti ,
Ciao!
>
>avrei bisgono di sapere come faccio a controllare che un determinato
>record che sto inserendo non sia già presente. Ho notato (ovviamente)
>che , ad ogni modifica del project, rieseguento l'elaborato per
>verificare i cambiamenti,mi inserisce in append gli stessi record.
Sì, ok, questo perchè probabilmente hai messo come chiave primaria un autoincrementante. Perchè se creassi l'opportuno vincolo unique sui campi che sono la tua "vera" chiave primaria (e non quella surrogata identity) l'inserimento solleverebbe un errore facilmente gestibile.

>Ora, mi chiedo:

>- Come posso verificare il funzionamente del mio progetto,dopo ogni mia modifica,senza inserire dei doppioni?
Questa domanda non ha più senso se leggi quanto detto sopra.

>- in generale,c'è un metodo automatizzato ho dovrei , attraverso TSQL, fare dei controlli prima di una qualsiasi INSERT?
Se vuoi saperlo a priori puoi usare la EXISTS:

IF EXISTS(SELECT * FROM tabella WHERE campochiave = <tuovalorechiave>) -- esiste ELSE -- non esists

EXISTS (transact-sql)
http://msdn.microsoft.com/it-it/library/ms188336.aspx

>-viceversa,nei DATA FLOW, come mi devo comportare?
Fai una lookup che controlla per chiave se esistono righe. Gestisci l'errore (ovvero quando i record non esistono) e ridirigi la freccia rossa verso la insert e la freccia verde, o la ignori oppure la dirigi verso un'eventuale update.

>Grazie
di nulla!

--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

the_driver Profilo | Senior Member

Grazie mille Alex,non uso chiavi autoincrementali. Comunque ci guarderò.

volevo inoltre chiederti una cosa:

Ho dei DB in sql server 2005 (su piattaforma windows 2003).

Devo fare il backup di tali db su un server ftp remoto;

cosa mi consigli di usare?


SSIS? oppure uno script bath? Hai qualche guida da consigliarmi?

Grazie mille per la disponibilità

alx_81 Profilo | Guru

>Gazie mille Alex,non uso chiavi autoincrementali. Comunque ci guarderò.
Se hai definito una chiave primaria, se il record che stai inserendo è identico ad uno già presente, avrai errore certo.
Prova a postare la struttura della tabella e un elenco di record che vengono comunque caricati..
>
>volevo inoltre chiederti una cosa:
>Ho dei DB in sql server 2005 (su piattaforma windows 2003).
>Devo fare il backup di tali db su un server ftp remoto;
>cosa mi consigli di usare?
>
>SSIS? oppure uno script bath? Hai qualche guida da consigliarmi?
Ma guarda, io starei su SSIS perchè le operazioni che devi fare sono eterogenee (prima il backup su disco, poi un transfer FTP)
Il mio blog

Per il backup, puoi fare un EXECUTE SQL Task con il comando BACKUP DATABASE:
http://msdn.microsoft.com/it-it/library/ms186865.aspx

Per l'ftp, ti rimando ad un link sul mio blog:
http://blogs.dotnethell.it/suxstellino/Altri-Task-del-Control-Flow__4148.aspx

lo accenno solamente, ma vedrai che è facile.
Puoi usare le expression per assegnare dinamicamente i valori ai tuoi task:
http://blogs.dotnethell.it/suxstellino/Le-Expressions__4228.aspx

>Grazie mille per la disponibilità
di nulla!
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

the_driver Profilo | Senior Member

Ti ringrazio per le tue celeri risposte, e ti garantisco che ora ho le idee + chiare.

Per quanto riguarda i link che mi hai postato verranno visti a breve.

Ti volevo comunque chiedere 2 cose:

una volta che farò il progetto di trasferimento con SISS,come faccio ad inserire un task automatizzato in windows che mi richiama il backup/progetto SISS?

Inoltre mi chiedevo, in CONTROL FLOW se utilizzo un un EXCECUTE SQL TASK,che memorizza i risultati di una query in una variabile object (da me definita globale),quindi tale variabile viene passata in un FOREACH , all'interno del quale inserisco un DATA FLOW,nel data folw selezionato come posso riutilizzare l'oggetto (o i campi dell'oggetto / risultati query ) come "sorgenti" per poi fare ,per esempio,dei script task o dei data convert che li utilizzano?

Generalmente non ho mai avuto necessita di fare questo,perche nei miei data flow ho sempre settato un oledb source e un oledb destination mappando i campi. Ma mi chiedevo come posso impostare una sorgente di tipo "object".


Grazie mille!

alx_81 Profilo | Guru

>una volta che farò il progetto di trasferimento con SISS,come faccio ad inserire un task automatizzato in windows che mi richiama il backup/progetto SISS?
Non puoi usare i JOB di SQL Server? Nel tuo SQL Server Management Studio, vedrai la voce SQL Server Agent, poi Jobs (processi). Lì puoi creare processi automatizzati con frequenza massima di un'esecuzione al minuto.

>Inoltre mi chiedevo, in CONTROL FLOW se utilizzo un un EXCECUTE SQL TASK,che memorizza i risultati di una query in una variabile
>object (da me definita globale),quindi tale variabile viene passata in un FOREACH , all'interno del quale inserisco un DATA FLOW,nel
>data folw selezionato come posso riutilizzare l'oggetto (o i campi dell'oggetto / risultati query ) come "sorgenti" per poi
>fare ,per esempio,dei script task o dei data convert che li utilizzano?
Continuo a non capire perchè usi questo metodo, perdonami ma io quel ciclo foreach non lo capisco. Già nel dataflow, le sorgenti, consentono il trattamento iterativo dei dati che passano nelle varie pipeline.. Comunque sia, il risultato di un execute SQL Task è purtroppo un Recordset COM. Di conseguenza dovrai usare uno Script Component come sorgente wrappando il Recordset (proprio è un oggetto COM, non .Net).

>Generalmente non ho mai avuto necessita di fare questo,perche
>nei miei data flow ho sempre settato un oledb source e un oledb
>destination mappando i campi.
E secondo me dovresti continuare a fare così
Poi tra la sorgente e la destinazione puoi mettere tutte le convert, le condizioni, i calcoli che ritieni opportuni. Fai attenzione ad abusare di execute sql task e foreach dove non servono. Hai già dataflow, e fino a prova contraria, dagli precedenza.

>Grazie mille!
di nulla!
--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

the_driver Profilo | Senior Member

Scusa,non capisco, uso foreach poichè, l'sqltask mi restituisce un elenco di USER_ID;
tali USER_ID devo prenderle singolarmente e riutilizzarle per un altra query.

Sono conscio del fatto che ,siccome sono agli inizi in SSIS,utilizzo metodi poco performanti,ma purtroppo ragiono ancora ad alto livello,nel senso che tratto il recordset come farei con vb o php,ovvero,ciclando su di esso prelevando le singole row.

Putroppo non riesco a capire come fare,con un dataflow, a sostituire questa operazione.

Ho proprio visto ieri i JOB,in merito al tuo aiuto per i backup,mi sapresti dire l'oggetto da richiamare nell'agent per eseguire un task SSIS? grazie

alx_81 Profilo | Guru

>Scusa,non capisco, uso foreach poichè, l'sqltask mi restituisce
>un elenco di USER_ID;
>tali USER_ID devo prenderle singolarmente e riutilizzarle per
>un altra query.
Ma non puoi fare una join? Immagino questa situazione di esempio:

- Tabella Utenti
- Tabella ContiCorrenti (l'utente è legato)

Fai una bella join tra le due tabelle, ordinando il resultset per utente, e la usi come sorgente del tuo DataFlow.
Poi definisci le trasformazioni da eseguire.
Magari prova a spiegare la situazione reale, potrebbe essere che non puoi fare a meno del foreach, ma, per quanto possibile, cerchiamo di sceglierlo come ultima spiaggia

>Sono conscio del fatto che ,siccome sono agli inizi in SSIS,utilizzo
>metodi poco performanti,ma purtroppo ragiono ancora ad alto livello,nel
>senso che tratto il recordset come farei con vb o php,ovvero,ciclando
>su di esso prelevando le singole row.
Eh capisco, ma allora scrivi un servizio . Se decidi di usare SSIS dovresti sfruttare le sue potenzialità, anche se, senza conoscere la situazione reale, faccio fatica a dirti se puoi cambiare l'approccio..

>Ho proprio visto ieri i JOB,in merito al tuo aiuto per i backup,mi
>sapresti dire l'oggetto da richiamare nell'agent per eseguire
>un task SSIS?
Che oggetto? Un job lo crei tramite sql Agent, definisci step e schedule e lui "va" da solo allo schedule definito da te, con la frequenza definita da te..

>grazie
di nulla!

--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

the_driver Profilo | Senior Member

>>Scusa,non capisco, uso foreach poichè, l'sqltask mi restituisce
>>un elenco di USER_ID;
>>tali USER_ID devo prenderle singolarmente e riutilizzarle per
>>un altra query.
>Ma non puoi fare una join? Immagino questa situazione di esempio:
>
>- Tabella Utenti
>- Tabella ContiCorrenti (l'utente è legato)
>
>Fai una bella join tra le due tabelle, ordinando il resultset
>per utente, e la usi come sorgente del tuo DataFlow.
>Poi definisci le trasformazioni da eseguire.
>Magari prova a spiegare la situazione reale, potrebbe essere
>che non puoi fare a meno del foreach, ma, per quanto possibile,
>cerchiamo di sceglierlo come ultima spiaggia
>
>>Sono conscio del fatto che ,siccome sono agli inizi in SSIS,utilizzo
>>metodi poco performanti,ma purtroppo ragiono ancora ad alto livello,nel
>>senso che tratto il recordset come farei con vb o php,ovvero,ciclando
>>su di esso prelevando le singole row.
>Eh capisco, ma allora scrivi un servizio . Se decidi di usare
>SSIS dovresti sfruttare le sue potenzialità, anche se, senza
>conoscere la situazione reale, faccio fatica a dirti se puoi
>cambiare l'approccio..
>
>>Ho proprio visto ieri i JOB,in merito al tuo aiuto per i backup,mi
>>sapresti dire l'oggetto da richiamare nell'agent per eseguire
>>un task SSIS?
>Che oggetto? Un job lo crei tramite sql Agent, definisci step
>e schedule e lui "va" da solo allo schedule definito da te, con
>la frequenza definita da te..
>
>>grazie
>di nulla!
>
>--
>
>Alessandro Alpi | SQL Server MVP
>
>http://www.alessandroalpi.net
>http://blogs.dotnethell.it/suxstellino
>http://mvp.support.microsoft.com/profile/Alessandro.Alpi
>http://italy.mvps.org


Ok sono daccordo con te con le join ma il mio problema è differente,nel senso che non posso effettuare il controllo che ho in mente attraverso delle join, in quanto ho necessità di fare dei confronti (attraverso degli if) tra 2 tabelle in base ad un id_utente. Devo verificare che dei campi siano diversi in tal caso devo poi controllare un altra tabella e prelevare dei valori in base all'id_utente utilizzato durante il controllo . Purtroppo è difficile da spiegare e come ti ho detto non posso postare le tabelle. eventualmente posso farti un esempio:


tra tutte le tabelle, ne Ho 5 tabelle (esempio):

UTENTE , UTENTE_JOB_ANNO_1_2 , UTENTE_JOB_ANNO_3_4 , UTENTE_JOB_ANNO_5_6 e FINE_JOB

UTENTE e UTENTE_JOB_ANNO_x_y sono in relazione tramite un ID_UTENTE mentre UTENTE_JOB_ANNO_x_y descive il job che stanno facendo (1_2 indica l' anno , ovvero JOB nel primo anno e JOB nel secondo anno,quindi nella tabella sono presenti 2 campi job)

FINE_JOB ha all'interno un campo ID_UTENTE , un campo DATA e un campo text DESCRIZIONE con il tipo di job terminato (stessa sigla presente in UTENTE_JOB_ANNO_x_y)

Dovrei , per ogni utente controllare, nei vari anni se il JOB a cui stanno lavorando è cambiato,prelevare da FINE_JOB la DATA di fine e la DESCRIZIONE.

Per esempio nel primo anno (campo anno1 in UTENTE_JOB_ANNO_1_2) l'user lavora come PROGRAMMATORE se nel campo anno2 c'è scritto SISTEMISTA devo leggere in FINE_JOB la data di fine e descrizione.

Ogni utente non può rifare lo stesso job una volta terminato. I risultati vengono memorizzati su un altro DB,in cui il tutto è gestito da un unica tabella CARRIERA , in cui sono presenti i seguenti campi ID_UTENTE,NOME,COGNOME,JOB,INIZIO,FINE . Quindi dovrei tracciare, per ogni utente la carriera lavorativa e segnalare pper ogni job inizio e fine .

alx_81 Profilo | Guru

>Ok sono daccordo con te con le join ma il mio problema è differente,nel
>senso che non posso effettuare il controllo che ho in mente attraverso
>delle join, in quanto ho necessità di fare dei confronti (attraverso
>degli if) tra 2 tabelle in base ad un id_utente. Devo verificare
>che dei campi siano diversi in tal caso devo poi controllare
>un altra tabella e prelevare dei valori in base all'id_utente
>utilizzato durante il controllo . Purtroppo è difficile da spiegare
>e come ti ho detto non posso postare le tabelle.
Ok, così non riesco ad aiutarti, ma sono sicuro che avrai studiato bene il problema
Direi che alla fine ci siamo allora
Se ritieni che le risposte ti abbiano aiutato accetta la risposta che chiudiamo il thread.
Ciao!

--

Alessandro Alpi | SQL Server MVP

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org
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