Wenn Daten aus zwei unterschiedlichen Tabellen über einen gemeinsamen Schlüssel zusammengefügt werden sollen, dann bedient man sich üblicherweise eines JOINs. Solange man sich innerhalb einer Datenquelle (Datenbank) befindet, funktioniert das gut. Was aber, wenn die Tabellen in zwei unterschiedlichen Datenquellen (und möglicherweise auch noch unterschiedlichen DBMS) liegen? Mit einem kleinen Trick lässt sich dieses Problem lösen.
Ein Beispiel
Gehen wir von folgendem Beispiel aus:
- Es liegen Bestellungen in der Tabelle
ORDERS
der Excel-Datei „C:\OMS\DBSRC1\dbsrc01.xlsx“ vor. - Die zugehörigen Kundeninformationen befinden sich in der Tabelle
CUSTOMERS
der ACCESS-Datenbank „C:\OMS\DBSRC2\dbsrc02.accdb“.
Die Tabellen sehen dabei in etwa folgendermaßen aus:
Wenn diese beiden Tabellen gemeinsam in einer Datenquelle liegen, kann man über ein JOIN-Statement recht einfach eine Auswertung über beide Tabellen durchführen, z.B.:
SELECT A.ORDER_ID, A.CUSTOMER_ID, B.LASTNAME, B.FIRSTNAME, A.PRODUCT_ID, A.AMOUNT FROM ORDERS AS A LEFT JOIN CUSTOMERS AS B ON A.CUSTOMER_ID = B.CUSTOMER_ID (WHERE …)
In diesem Fall ist das jedoch nicht möglich, weil die beiden Tabellen in unterschiedlichen Datenbanken liegen.
Die Lösung
Mit der Hilfe temporärer Tabellen, kann man die Auswertung im ODBC Management Studio folgendermaßen auch über zwei unterschiedliche DBMS hinweg durchführen:
- ODBC-Datenquelle (z.B. DB_SRC1) für die Excel-Datei „C:\OMS\DBSRC1\dbsrc01.xlsx“ anlegen.
- ODBC-Datenquelle (z.B. DB_SRC2) für die ACCESS-Datenbank „C:\OMS\DBSRC2\dbsrc02.accdb“ anlegen.
- ODBC-Datenquelle (z.B. DB_DST) als Ziel für das Ergebnis der Auswertung (und die temporären Tabellen) anlegen. Hierfür verwenden wir den ODBC-Text-Treiber, der auf ein das leere Verzeichnis „C:\OMS\DBDST\“ zeigt:
- Nun schreiben wir ein OSL-Skript, das in etwa die folgenden Anweisungen ausführt:
- Schreibe alle relevanten Daten aus der Tabelle ORDERS in die temporäre Tabelle „ORDS.tmp“ der Datenquelle DB_DST.
- Schreibe alle relevanten Daten aus der Tabelle CUSTOMERS in die temporäre Tabelle „CUST.tmp“ der Datenquelle DB_DST.
- Führe einen JOIN auf diese beiden temporären Tabellen der Datenquelle DB_DST aus und schreibe das Ergebnis in die Zieltabelle „Result.txt“ der Datenquelle DB_DST.
- Lösche die Temporären Tabellen
Das OSL-Skript für das ODBC Management Studio
Mit dem folgenden OSL-Skript wurde diese Lösung getestet wurde. Die dabei verwendeten Makros blähen den Code einwenig auf, können aber durchaus auch weggelassen werden. Aus meiner Sicht ist es so etwas leichter lesbar.
-------------------------------------------------------------------- -- OMS-SL Skript: -- Daten aus zwei unterschiedlichen Datenbanken in einer -- (neuen) Tabelle vereinen. -------------------------------------------------------------------- -- Autor.....: hermannschristoph -- Datum/Zeit: 23.01.2018 21:42:01 -------------------------------------------------------------------- -------------------------------------------------------------------- -- Initialisierung BATCHMODE OFF; GRIDVIEW OFF; GRIDVIEW MAXROWS 150; TEXTEXPORT ON; TEXTEXPORT SEPARATOR ","; -- Use default CSV TEXTEXPORT COLNAMES ON; TEXTEXPORT ROWNUMBERS OFF; TEXTEXPORT QUOTES OFF; TEXTEXPORT CODING ANSI; -------------------------------------------------------------------- -- Namen für temporäte Tabellen DEFINE MAKRO __ORDS_TABL_TMP "ORDS.tmp"; DEFINE MAKRO __CUST_TABL_TMP "CUST.tmp"; DEFINE MAKRO __ORDS_FILE_TMP "C:\\OMS\\DBDST\\$(__ORDS_TABL_TMP)"; DEFINE MAKRO __CUST_FILE_TMP "C:\\OMS\\DBDST\\$(__CUST_TABL_TMP)"; -------------------------------------------------------------------- -- Name der Zieltabelle DEFINE MAKRO __RESULT_TABL "Result.txt"; DEFINE MAKRO __RESULT_FILE "C:\\OMS\\DBDST\\$(__RESULT_TABL)"; -------------------------------------------------------------------- -- DBSRC01, Excel-Tabelle CONNECT USER_DSN "DB_SRC1"; TEXTEXPORT FILENAME $(__ORDS_FILE_TMP); -- Temp. Tab 1 anlegen SELECT `ORDER_ID`, `CUSTOMER_ID`, `PRODUCT_ID`, `AMOUNT` FROM `ORDERS$`; DISCONNECT; -------------------------------------------------------------------- -- DBSRC01, Access-Datenbank CONNECT USER_DSN "DB_SRC2"; TEXTEXPORT FILENAME $(__CUST_FILE_TMP); -- Temp. Tab 2 anlegen SELECT `CUSTOMER_ID`, `LASTNAME`, `FIRSTNAME` FROM `CUSTOMERS`; DISCONNECT; -------------------------------------------------------------------- -- DBSRC01, Text-Datei GRIDVIEW ON; -- GRID wieder einschalten, um Ergebnis anzuzeigen CONNECT USER_DSN "DB_DST"; TEXTEXPORT FILENAME $(__RESULT_FILE); -- Zieltabelle anlegen SELECT A.`ORDER_ID`, B.`CUSTOMER_ID`, B.`LASTNAME`, B.`FIRSTNAME`, A.`PRODUCT_ID`, A.`AMOUNT` FROM `$(__ORDS_TABL_TMP)` AS A LEFT JOIN `$(__CUST_TABL_TMP)` AS B ON A.`CUSTOMER_ID` = B.`CUSTOMER_ID`; DROP TABLE $(__ORDS_TABL_TMP); -- Temp. Tab 1 löschen DROP TABLE $(__CUST_TABL_TMP); -- Temp. Tab 2 anlegen DISCONNECT; -------------------------------------------------------------------- UNDEFINE MAKRO __ORDS_FILE_TMP; UNDEFINE MAKRO __CUST_FILE_TMP; UNDEFINE MAKRO __ORDS_TABL_TMP; UNDEFINE MAKRO __CUST_TABL_TMP; -------------------------------------------------------------------- -- Ergebnis darstellen (?) EXECUTE PROGRAM "Notepad++.exe" "$(__RESULT_FILE)"; UNDEFINE MAKRO __RESULT_FILE; UNDEFINE MAKRO __RESULT_TABL;
Nach der Ausführung des Skripts wird die Ergebnistabelle auch im GRID dargestellt. Der folgende abschließende Screenshot zeigt einen Teil des Skripts, das Ergebnis-GRID und den wesentlichen Teil des verwendeten Datenbank-übergreifenden Schemas: