SQL-JOINs über Tabellen aus unterschiedlichen Datenbanken und Datenbanksystemen

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:

  1. ODBC-Datenquelle (z.B. DB_SRC1) für die Excel-Datei „C:\OMS\DBSRC1\dbsrc01.xlsx“ anlegen.
  2. ODBC-Datenquelle (z.B. DB_SRC2) für die ACCESS-Datenbank „C:\OMS\DBSRC2\dbsrc02.accdb“ anlegen.
  3. 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:
  4. Nun schreiben wir ein OSL-Skript, das in etwa die folgenden Anweisungen ausführt:
    1. Schreibe alle relevanten Daten aus der Tabelle ORDERS in die temporäre Tabelle „ORDS.tmp“ der Datenquelle DB_DST.
    2. Schreibe alle relevanten Daten aus der Tabelle CUSTOMERS in die temporäre Tabelle „CUST.tmp“ der Datenquelle DB_DST.
    3. 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.
    4. 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:

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.