Exceptionfault
Erfahrenes Mitglied
Gerade in großen Unnternehmen, mit verteilten Anwendungen und Standorten kommt es auch häufig zu verteilter Datenhaltung. In einem Standort sind Kundendaten, im nächsten wieder Lieferanten, und ganz wo anders Personaldaten. Was aber nun wenn man alle daten für eine Auswertung braucht ?
Häufig gibt es dann komplizierte Schnittstellen über Export und Import. Das führt zu redundaten Daten, Übertragungsfehlern und aktuell sind die Daten schon gar nicht. Ein schönes Feature von Oracle um so etwas zu verhindern sind Datenbanklinks. Es ist also möglich von einer Datenbank aus auf eine entfernte Datenbank zuzugreifen und Daten auszutauschen. Das ganze lässt sich sogar transparent für Applikationen aufziehen, so dass eine Applikation z.B. auf 3 Datenbanken weltweit verteilt arbeitet. Mit einem stabilen und schnellen Netzwerk überhaupt kein Problem.
Nun, ein einfacher Datenbanklink zwischen 2 Oracle Datenbanken ist schnell erklärt:
Mit dem obigen Statement kann ich einfach einen Datenbanklink zu einer anderen Oracle Datenbank einrichten. Nutzen kann ich diesen Link dann etwa folgendermassen:
Mache ich aus dem obigen Statement eine View, merkt kein Mensch mehr, wo die Daten eigentlich stehen...
Mit dem @ hinter der Tabelle gebe ich also "den Ort" bekannt über welchen Link die Tabelle zu finden ist. Der Eintrag "USING 'xyz'" ist der Alias der Datenbank über den Oracle den Namen in eine Adresse und Port auflöst. MY_SND_DB muss also auf dem lokalen Server in der TNSNAMES.ORA gepflegt sein. CONNECT TO und IDENTIFIED BY geben den Benutzernamen und das Passwort an, mit dem ich mich an der fremden Datenbank anmelde. Das Passwort steht wohlgemerkt in " ", was unbedingt nötig ist, wenn es in meinem Passwort auf Groß- und Kleinschreibung ankommt.
Nun, das wars eigentlich schon fast zu Datenbank Links. Aber als Tutorial etwas mager, oder?
Deshalb dachte ich wir experimentieren ein bisschen und machen das selbe auch mal zwischen einer Oracle und einer NICHT Oracle Datenbank. Ja, das geht auch ;-)
Voraus muss ich sagen, ich habe das schon etliche male gemacht, zwischen diversen DB Systemen und Oracle, allerdings immer unter Windows. Zu Hause bin ich seit kurzem auf Linux und somit war es auch ein bisschen Neuland. Ich hab auch noch einen kleines Problem, aber unter Windows lief es bisher immer einwandfrei, daher denke ich wird das unter Linux auch noch klappen.
Ich hab mich für mySQL entschieden, damit können hier einige mehr anfangen ;-)
1.) Zunächst müssen wir den myODBC Treiber passend zu unserer mySQL Datenbank installieren. Was unter Windows simpel ist hat mich unter Linux gestern mehrere Stunden gekostet *g*. Und nach erfolgreicher Installation eine System DSN einrichten. Es sollte auf jeden Fall der Host (bei mir localhost), der User (bei mir kaiser) und die Datenbank (auch kaiser) in die Voreinstellung eingetragen werden. Ideallerweise sollte man die Connection dann auch mal testen, z.B. über MsQuery in Excel oder so. In meinem Beispiel heisst die DSN "myodbc", wie der Treiber...
2.) Als nächstes müssen wir dem Listener auf unserem Oracle Server mitteilen welches Programm er zum connecten nutzen soll. Hierfür stellt Oracle das Tool "hsodbc" zur Verfügung. Es gibt auch "hsoledb" etc, aber mir hat odbc unter Linux erstmal genügt. Btw. HS steht für Heterogene Services.
Bei mir sah die Listener.ora (Pfad: $ORACLE_HOME/network/admin) nach der Konfiguration so aus (das fette ist neu, bodev ist meine lokale Oracle DB):
Den Listener müssen wir nach der Änderung neu starten, entweder über den Service unter Windows oder mit "lsnrctl reload".
Auch die TNSNAMES.ORA müssen wir anpassen und die fremde Datenbank bekannt machen:
In meinem Fall, lag die mySQL DB auf dem selben Rechner, was jedoch nicht zwingend ist. Vergesst das "HS=OK" nicht, es kostet Stunden diesen Fehler zu suchen *g*.
Ein File fehlt jedoch noch: Zu finden im Verzeichnis $ORACLE_HOME/hs/admin liegt eine initHSODBC.ini. Davon machen wir eine Kopie und nennen sie nach dem Schema: init + DSN + ".ora". Bei mir also "initmyodbc.ora". Ich hab leider kein Configfile mehr von Windows, daher kann ich nicht genau sagen, welche der gleich folgenden Parameter für Windows nötig sind, aber ich glaube es müsste "HS_FDS_CONNECT_INFO" reichen.
Bei mir sah das File dann so aus:
Das wars sogar schon fast. Jetzt kann ich in Oracle meinen Datenbanklink anlegen. Als Parameter für USING einfach den Eintrag aus der TNSNAMES.ORA nehmen (myodbc, was sonst?!). Beim Zugriff auf mySQL muss man leider IMMER auf Groß- und Kleinschreibung achten, ansonsten schreibt Oracle alles groß. Daher muss z.B. auch der Username beim erstellen des Links in " ".
Beim Zugriff auf Tabellen macht dies das Statement etwas hässlich, aber es funktioniert:
Einziges Problem: Man sieht, dass beim DESCRIBE keine Precision der VARCHAR2 Felder angegeben ist. Daher zeigt Oracle das Ergebnis leider etwas seltsam an. Da muss ich mal noch mit nem anderen ODBC Treiber experimentieren... aber soweit schonmal nicht schlecht, oder ? Achso, INSERT, DELETE etc... geht natürlich auch. Man darf eben nur keine Keywords von Oracle wie z.B. SYSDATE verwenden, da er ja die Statements an den mySQL Server weiterreit.
Häufig gibt es dann komplizierte Schnittstellen über Export und Import. Das führt zu redundaten Daten, Übertragungsfehlern und aktuell sind die Daten schon gar nicht. Ein schönes Feature von Oracle um so etwas zu verhindern sind Datenbanklinks. Es ist also möglich von einer Datenbank aus auf eine entfernte Datenbank zuzugreifen und Daten auszutauschen. Das ganze lässt sich sogar transparent für Applikationen aufziehen, so dass eine Applikation z.B. auf 3 Datenbanken weltweit verteilt arbeitet. Mit einem stabilen und schnellen Netzwerk überhaupt kein Problem.
Nun, ein einfacher Datenbanklink zwischen 2 Oracle Datenbanken ist schnell erklärt:
Code:
CREATE PUBLIC DATABASE LINK MY_SND_DB
CONNECT TO username
IDENTIFIED BY "geHeiM"
USING 'MY_SND_DB';
Code:
SELECT * FROM SALES@MY_SND_DB;
Mit dem @ hinter der Tabelle gebe ich also "den Ort" bekannt über welchen Link die Tabelle zu finden ist. Der Eintrag "USING 'xyz'" ist der Alias der Datenbank über den Oracle den Namen in eine Adresse und Port auflöst. MY_SND_DB muss also auf dem lokalen Server in der TNSNAMES.ORA gepflegt sein. CONNECT TO und IDENTIFIED BY geben den Benutzernamen und das Passwort an, mit dem ich mich an der fremden Datenbank anmelde. Das Passwort steht wohlgemerkt in " ", was unbedingt nötig ist, wenn es in meinem Passwort auf Groß- und Kleinschreibung ankommt.
Nun, das wars eigentlich schon fast zu Datenbank Links. Aber als Tutorial etwas mager, oder?
Deshalb dachte ich wir experimentieren ein bisschen und machen das selbe auch mal zwischen einer Oracle und einer NICHT Oracle Datenbank. Ja, das geht auch ;-)
Voraus muss ich sagen, ich habe das schon etliche male gemacht, zwischen diversen DB Systemen und Oracle, allerdings immer unter Windows. Zu Hause bin ich seit kurzem auf Linux und somit war es auch ein bisschen Neuland. Ich hab auch noch einen kleines Problem, aber unter Windows lief es bisher immer einwandfrei, daher denke ich wird das unter Linux auch noch klappen.
Ich hab mich für mySQL entschieden, damit können hier einige mehr anfangen ;-)
1.) Zunächst müssen wir den myODBC Treiber passend zu unserer mySQL Datenbank installieren. Was unter Windows simpel ist hat mich unter Linux gestern mehrere Stunden gekostet *g*. Und nach erfolgreicher Installation eine System DSN einrichten. Es sollte auf jeden Fall der Host (bei mir localhost), der User (bei mir kaiser) und die Datenbank (auch kaiser) in die Voreinstellung eingetragen werden. Ideallerweise sollte man die Connection dann auch mal testen, z.B. über MsQuery in Excel oder so. In meinem Beispiel heisst die DSN "myodbc", wie der Treiber...
2.) Als nächstes müssen wir dem Listener auf unserem Oracle Server mitteilen welches Programm er zum connecten nutzen soll. Hierfür stellt Oracle das Tool "hsodbc" zur Verfügung. Es gibt auch "hsoledb" etc, aber mir hat odbc unter Linux erstmal genügt. Btw. HS steht für Heterogene Services.
Bei mir sah die Listener.ora (Pfad: $ORACLE_HOME/network/admin) nach der Konfiguration so aus (das fette ist neu, bodev ist meine lokale Oracle DB):
Code:
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = sphinx.exceptionfault)(PORT = 1521))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC) (KEY = BODEV))
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = bodev.exceptionfault)
(ORACLE_HOME = /home/oracle/oracle/product/10.2.0/db_1)
(SID_NAME = bodev)
)
(SID_DESC =
(ORACLE_HOME = /home/oracle/oracle/product/10.2.0/db_1)
(SID_NAME = myodbc)
(PROGRAM = hsodbc)
)
)
Auch die TNSNAMES.ORA müssen wir anpassen und die fremde Datenbank bekannt machen:
Code:
bodev =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = bodev))
(ADDRESS = (PROTOCOL = TCP)(HOST = sphinx.exceptionfault)(Port = 1521))
)
(CONNECT_DATA =
(SID = bodev)
)
)
myodbc =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = sphinx.exceptionfault)(Port = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = myodbc)
)
(HS = OK)
)
Ein File fehlt jedoch noch: Zu finden im Verzeichnis $ORACLE_HOME/hs/admin liegt eine initHSODBC.ini. Davon machen wir eine Kopie und nennen sie nach dem Schema: init + DSN + ".ora". Bei mir also "initmyodbc.ora". Ich hab leider kein Configfile mehr von Windows, daher kann ich nicht genau sagen, welche der gleich folgenden Parameter für Windows nötig sind, aber ich glaube es müsste "HS_FDS_CONNECT_INFO" reichen.
Bei mir sah das File dann so aus:
Code:
HS_FDS_CONNECT_INFO = myodbc
HS_FDS_TRACE_LEVEL = 0
HS_FDS_SHAREABLE_NAME = /usr/lib/unixODBC/libmyodbc3-3.51.10.so
set ODBCINI=/etc/unixODBC/odbc.ini
Beim Zugriff auf Tabellen macht dies das Statement etwas hässlich, aber es funktioniert:
Code:
sphinx:~ # mysql -u kaiser -p kaiser
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16 to server version: 4.1.10a
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> select * from users;
+-------+----------+----------+------------+-------+
| pk_id | username | password | last_login | email |
+-------+----------+----------+------------+-------+
| 1 | Andreas | test | 2005-08-24 | no |
+-------+----------+----------+------------+-------+
1 row in set (0.03 sec)
mysql> exit
Bye
sphinx:~ # sqlplus /nolog
SQL*Plus: Release 10.2.0.1.0 - Production on Wed Aug 24 20:24:34 2005
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> conn / as sysdba
Connected.
SQL> create public database link myodbc connect to "kaiser" identified by "test" using 'myodbc';
Database link created.
SQL> desc "users"@myodbc
Name Null? Type
----------------------------------------- -------- ----------------------------
pk_id NUMBER(10)
username NOT NULL VARCHAR2
password NOT NULL VARCHAR2
last_login NOT NULL DATE
email NOT NULL VARCHAR2
SQL> select * from "users"@myodbc;
pk_id username passw last_logi ema
---------- -------- ----- --------- ---
1 Andreas test 24-AUG-05 no
Einziges Problem: Man sieht, dass beim DESCRIBE keine Precision der VARCHAR2 Felder angegeben ist. Daher zeigt Oracle das Ergebnis leider etwas seltsam an. Da muss ich mal noch mit nem anderen ODBC Treiber experimentieren... aber soweit schonmal nicht schlecht, oder ? Achso, INSERT, DELETE etc... geht natürlich auch. Man darf eben nur keine Keywords von Oracle wie z.B. SYSDATE verwenden, da er ja die Statements an den mySQL Server weiterreit.