Selezionare dati distribuiti fra 2 database separati...

domenica 16 novembre 2008 - 20.33

Teech Profilo | Expert

Ho una struttura nella quale i dati sono distribuiti fra 2 database. Praticamente gli utenti utilizzano un gestionale dove inseriscono i clienti e gli ordini ed i dati vanno a finire su un database. E' presente una personalizzazione nel gestionale che leggendo i dati degli ordini, attraverso delle specifiche definite, scrive delle commesse su un database creato da me per la gestione della procedura. In questi termini mi ritrovo una tabella commesse contenente un campo codice cliente che univocamente mi identifica un record della tabella clienti del database del gestionale.
Ora ho creato delle strutture che attraverso dei datatable tipizzati (creati da codice, non da visual studio) popolano delle classi collection contenenti delle classi specializzate per la gestione dei clienti e delle commesse.
Il problema che mi trovo ad affrontare è che non necessariamente tutti i clienti del gestionale hanno delle commesse nel programma da me gestito e quindi vorrei visualizzare di conseguenza solo i clienti che hanno commesse (in vari stadi di gestione come aperte, chiuse, in corso, ecc...) come se la tabella clienti fosse relazionata con la tabella commesse (uno a molti): essendo le 2 tabelle su database diversi questo è impossibile da gestire da SQL (o forse semplicemente io non so come fare).
La cosa più semplice che ho pensato è stata: posso passare un array come parametro di un SQLCommand? se si come posso poi gestirlo nel SQLCommand (o Stored Procedure) stesso?
In altro modo, come mi consigliate di comportarmi? Come posso fare questa selezione non avendo il termine di selezione nella tabella (visualizzare solo i clienti che hanno commesse). Un ulteriore ostacolo è che vorrei mantenere le mie classi di gestione dei dati così come sono ora per questioni di portabilità (posso utilizzare l'ereditarietà per estendere le classi e credo che il problema possa essere comunque risolto, ma preferisco precisarlo).

Avete qualche consiglio o dritta da darmi in merito?

Grazie!!!
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

tonyexpo Profilo | Senior Member

Ciao

se non puoi collegare i DB in automatico puoi fare un paio di select diverse tipo queste:

--db gestionale
select TUOID from tabellagestionale

--db ordini
select quellochetiserver FROM tuatabella where chiaveesterna IN
(elenco chiavi precedenti separate da virgola)


Es seconda query:

dim tuoarray as string() = elenco chiavi in prima query

dim s as string = String.Join(",", tuoarray).TrimEnd(",")
dim query2 as string = "SELECT * FROM tuatabella WHERE chiaveesterna IN (" & s & ")"


Antonio Esposito
MCP, MCTS .NET 2.0 Distributed applications

Teech Profilo | Expert

Avevo pensato di usare la 'IN' in SQL ma non sapevo esattamente come costruire la "lista"... Grazie mille...
Un'altro dubbio a riguardo: potrei avare anche centinaia di chiavi da mettere nella IN: esiste un limite in questo senso? (non ho trovato nulla di documentato...)

Grazie
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

lbenaglia Profilo | Guru

>Avete qualche consiglio o dritta da darmi in merito?

Ciao Maurizio,

Per risponderti adeguatamente dovremmo avere la struttura delle due tabelle (CREATE TABLE), alcuni dati di prova ed il result set finale che vorresti ottenere.
I due db risiedono sulla stessa istanza o su istanze differenti?
Probabilmente puoi risolvere il problema eseguendo una JOIN tra le due tabelle, ma ripeto, dovresti fornirci ulteriori dettagli per ricevere un aiuto più mirato.

>Grazie!!!
Prego.

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

Teech Profilo | Expert

I Database possono anche essere su istanze diverse.
Nel Database del gestionale ho la tabella Clienti così composta
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Nel Database da me gestito ho la tabella Commesse così composta
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Quello che vorrei ottenere è un elenco di clienti (raggruppati) che hanno delle commesse ed eventualmente decidere anche un ulteriore filtro opzionale per 'Stato' della commessa alla bisogna...

L'applicazione che stò creando è una Windows Application che si connette ai DB da più postazioni ma senza servizi centralizzati... Avevo pensato ai Linked server ma ad ogni apertura di un client dovrei creare un linked server diverso o comunque non saprei come gestirlo non avendo coscienza di ciò che altri client possono aver fatto (non so se mi sono spiegato...).
Attualmente ho una classe collection per ogni tabella (popolate da dei TableAdapter) e per ogni record o fatto il parsing a delle mie classi specializzate... Il problema è mettere in relazione le collection o più a monte le tabelle dei database... E' per questo che ho bisogno di una dritta su come comportarmi (come avrai capito non riesco nemmeno a spiegare il problema tanta è la confusione che ho in testa )

Grazie
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

lbenaglia Profilo | Guru

>I Database possono anche essere su istanze diverse.
Se i db risiedono su istanze diverse dovrai definire 1 linked server sull'istanza che preferisci che vada a puntare l'istanza remota, utilizzando il four-part name per referenziare la tabella remota (server.database.schema.tabella); diversamente sei i db risiedono nella stessa istanza potrai referenziare la tabella remota mediante three-part name (database.schema.tabella).

>Quello che vorrei ottenere è un elenco di clienti (raggruppati)
>che hanno delle commesse ed eventualmente decidere anche un ulteriore
>filtro opzionale per 'Stato' della commessa alla bisogna...
Raggruppati come?
Puoi postare il result set che vuoi ottenere in base ai dati postati?

>Avevo pensato ai Linked server ma ad ogni apertura di un client
>dovrei creare un linked server diverso o comunque non saprei
>come gestirlo non avendo coscienza di ciò che altri client possono
>aver fatto (non so se mi sono spiegato...).
Non ti sei spiegato
Il Linked Server lo crei 1 volta sola a livello di istanza, non ha alcuna correlazione con i client che vi accedono.

>Grazie
Prego.

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

Teech Profilo | Expert

Non avevo capito che i linked server erano a livello di istanza... Pensavo di dover lanciare ad ogni apertura del client una stored procedure tipo
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
e di conseguenze alla chiusura rimuovere il linked server con
EXEC sp_dropserver @ServerName, droplogins
dovendo di conseguenza generare un nome server diverso per ogni client e gestire gli accessi al server utilizzando il nome in modo dinamico (un suicidio in parole povere).
Però, generando un linked server a livello di istanza risolvo tutti i miei problemi...
Un'ultima cosa: per fare SELECT su tabelle del linked server devo necessariamente utilizzare una struttura tipo
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
oppure posso usare una query del tipo
SELECT Campo, Campo2 FROM Server.Database.Schema.Tabella WHERE Campo3=@Campo3
?

E comunque qual'è consigliato come sistema a livello prestazionale?

Grazie mille!!!
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

lbenaglia Profilo | Guru

>Un'ultima cosa: per fare SELECT su tabelle del linked server
>devo necessariamente utilizzare una struttura tipo
>SELECT Campo, Campo2 FROM OPENQUERY ('Server, SELECT Campo1,
>Campo2, Campo3 FROM Tabella') WHERE Campo3=@Campo3
>oppure posso usare una query del tipo
>SELECT Campo, Campo2 FROM Server.Database.Schema.Tabella WHERE
>Campo3=@Campo3
>?
Puoi utilizzare entrambe le tecniche.
OPENQUERY viene utilizzata per eseguire query pass-through, ovvero per eseguire remotamente la query; nel secondo esempio invece la query sarà risolta localmente.
Ad esempio se vai ad eseguire una SELECT su una tabella di 10 milioni di righe per restituirne una sola, sarà opportuno eseguire la query remotamente via OPENQUERY

>E comunque qual'è consigliato come sistema a livello prestazionale?
Verifica i piani di esecuzione di entrambe le query, ed utilizza la tecnica che offre le migliori prestazioni nel tuo caso

>Grazie mille!!!
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
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-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5