A volte è necessario lanciare delle query le cui join sono su tabelle che stanno su databases diversi o ancora su piattaforme diverse; con SQL Server è possibile fare questo grazie al comando openquery che di fatto restituisce una tabella proveniente da una query eseguita su un altro server, la query può essere anche molto complessa, l'importqante è che sia corretta per i DBMS sui quali si lancia, quindi se la query deve interrogare un DB2 bisogna utilizzare le il dialetto del DB2 (rispettivamente Oracle se ci colleghiamo ad un DBMS Oracle).
La chiave di tutto è sfruttare i linked server di SQL Server. E' possibile quindi fare delle join tra tabelle SQL Server ed altre tabelle appartenente a databases completamente diversi come DB2 o Oracle o addirittura fogli Excel. I passi standard principali da seguire sono:
Visto che quasi tutti hanno una dimestichezza con l'ODBC è conveniente creare prima una connessione ODBC con la fonte dati da interrogare per poi creare il linked Server in modo molto semplice a partire da una fonte dati ODBC. I linked server possono essere creati a partire dall'Enterprise Manager o dal Query Analizer tramite la stored procedure sp_addlinkedserver la cui sintassi Transact-SQL è la seguente:
sp_addlinkedserver [ @server = ] 'server' [ , [ @srvproduct = ] 'product_name' ] [ , [ @provider = ] 'provider_name' ] [ , [ @datasrc = ] 'data_source' ] [ , [@location =] 'location' ] [ , [ @provstr = ] 'provider_string' ] [ , [ @catalog = ] 'catalog' ]
Argomenti
[ @server =] 'server' è il nome del linked Server che si vuole creare e che verrà utilizzato successivamente per la openquery o del server in caso di un altro SQL Server.
[ @srvproduct = ] 'product_name', Nome del prodotto dell'origine dati OLE DB che si vuole aggiungere come linked server.
Se è uguale a SQL Server, non è necessario specificare gli argomenti provider_name, data_source, location, provider_string e catalog.
[ @provider = ] 'provider_name' Nome del provider, vedere la tabella inserita dopo.
[ @datasrc = ] 'data_source' Nome dell'origine dati.
[ @provstr = ] 'provider_string' Stringa di connessione, specifica per il provider ODBC.
[ @catalog = ] 'catalog' Nome del catalogo del database (solo per DB2).
Questa è la tabella riepilogativa che può essere molto utile per creare linked Server, onestamente non ricordo mai i parametri e sono costretto a rivederla ogni volta.
Origine dati OLE DB remota | Provider OLE DB |
product_name |
provider_name |
data_source |
location |
'provider_string' |
catalog |
---|---|---|---|---|---|---|---|
SQL Server | Provider OLE DB Microsoft per SQL Server | SQL Server (predefinito) |
- | - | - | - | - |
SQL Server | Provider OLE DB Microsoft per SQL Server | SQL Server | SQLOLEDB | Nome di rete di SQL Server (per l'istanza predefinita) | - | - | Nome di database (facoltativo) |
SQL Server | Provider OLE DB Microsoft per SQL Server | - | SQLOLEDB | Servername\instancename (per un'istanza specifica) | - | - | Nome di database (facoltativo) |
Oracle | Provider Microsoft OLE DB per Oracle | Qualsiasi prodotto | MSDAORA | Alias SQL*Net per database Oracle | - | - | - |
Access/Jet | Provider Microsoft OLE DB per Jet | Qualsiasi prodotto | Microsoft.Jet.OLEDB.4.0 | Percorso completo del file di database Jet | - | - | - |
Origine dati ODBC | Provider Microsoft OLE DB per ODBC | Qualsiasi prodotto | MSDASQL | DSN di sistema di origine dati ODBC | - | - | - |
Origine dati ODBC | Provider Microsoft OLE DB per ODBC | Qualsiasi prodotto | MSDASQL | - | - | stringa di connessione ODBC | - |
File system | Provider Microsoft OLE DB per Servizio indicizzazione | Qualsiasi prodotto | MSIDXS | Nome del catalogo del Servizio di indicizzazione | - | - | - |
Foglio di calcolo di Microsoft Excel | Provider Microsoft OLE DB per Jet | Qualsiasi prodotto | Microsoft.Jet.OLEDB.4.0 | Percorso completo del file Excel | - | Excel 5.0 | - |
Database IBM DB2 | Provider OLE DB per DB2 | Qualsiasi prodotto | DB2OLEDB | - | - | Vedere la documementazione del provider OLE DB per DB2 | Nome del catalogo del database DB2 |
Maggiori approfondimenti sulla creazione dei linked server possono essere trovati sull'help on line di SQL Server. Le autorizzazioni di esecuzione vengono date agli amminsitratori del DBMS, questo di default chiaramente possono essere attribuite anche ad altri membri.
select tabellaSQLServer.campo1, X.campo2, X.campo3 from tabellaSQLServer join openquery(nomeLinkedServer, 'select * from AltraTabella where Condizione=1') X on tabellaSQLServer.campoSQLServer = X.campoAltraTabella
Dove tabellaSQLServer è il nome della tabella residente nel database SQL Server, nomelinkedserver è il nome del linke dserver cha abbiamo creato precedentemente, AltraTabella è il nome della tabella presente nel database NON SQL Server, campoSQLServer e campoAltraTabella sono i rispettivi campi su cui fare la join.
Da tenere presente che dovendo fare un esempio si è scelti la query più semplice, ma nulla vieta di lanciare sul server remoto query complesse con selezioni particolari di campi e join con diverse tabelle del database SQL Server.
Importante, però, è tenere presente che SQL Server scarica TUTTI i record individuati nella query remota in una tabella temporanea, quindi evitare di fare query molto generiche.
Creo il linked Server basandomi su una connessione ODBC
sp_addlinkedserver @server ='mionuovolinkedserver', @srvproduct = 'nomeacaso', @provider = 'MSDASQL', @provstr = 'DSN=miafonteodbc;UID=sa;PWD=miapassword'e richiamo il linkedserver appena creato
select * from openquery(mionuovolinkedserver,'select * from tabella1')