Allgemeines
MapEdit Desktop und MapEdit Professional unterstützen zur Zeit 3 Datenbanktypen:
- Oracle
- SQLite
- Postgres
- (langfristig auch SQLServer)
Historisch wurde MapEdit zuerst auf Oracle unterstützt, später kam dann die Möglichkeit dazu Datenbanken nach SQLite zu exportieren um diese auf Auskunftsmaschinen mit zu nehmen. Seit einigen Jahren werden ausserdem auch Postgres Datenbanken unterstützt.
In MapEdit werden an vielen Stellen SQLs zur Konfiguration verwendet, z.B. in:
- Suchen
- Steuerelemente in Generic Formularen (z.B. SQL Labels, SQL TextBoxen etc)
- Darstellungsmodelle (Professional)
- VB und C# Script Funktionen
- Eigene .NET Plugins (Eigene Programm Erweiterungen) mit der MapEdit API.
- uvm.
MapEdit Datenmodel
MapEdit unterstützt das MapEdit Eigene Datenmodel und das Autodesk Map3D (Topobase) Datenmodel.
In beiden Datenmodellen sollten sie immer eine über alle Tabellen eindeutige FID verwenden. Bitte vermeiden sie das einfügen doppelter FIDs mittels Drittwerkzeugen bzw manuellen SQLs, da diese zu Problemen führen kann. Das einfügen von doppelten FIDs wird von MapEdit nicht verhindert!
Wenn man Datensätze via Script oder FME etc einfügen will und man die FID automatisch vergeben lassen will dann muss man beim INSERT bei FID den Wert 0 angeben. Dann wird ein Trigger ausgeführt der die nächste FID automatisch vergibt. Die FID wird über die Sequenze 'ME_NEXT_FID' vergeben.
Im MapEdit Datenmodel gibt es im Gegensatz zum Map3D keine Tabelle TB_UFID. Deswegen wird im MapEdit Datenmodel bei FID Verweisfeldern an Stellen wo die FID in mehreren Tabellen stehen könnte zusätzlich ein Feld XX_TABLE_NAME angelegt.
Das MapEdit Datenmodell verwaltet die als nächstes zu vergebende FID über eine Datenbank Sequenz (ME_NEXT_FID).
Das verwenden von Triggern wird in MapEdit Datenmodell und den Fachschalen vermieden und durch die Verwendung von Feature Rules (Software seitige Trigger) ersetzt, damit die Software mit verschiedenen Datenbanktypen (Oracle,Postgres, SQLite, SQLServer) gleichzeitig funktionieren kann ohne diese Trigger in jeder Datenbank neu schreiben zu müssen.
Sie können eigen Datenbank Trigger anlegen, jedoch können diese z.B. von den Datenmodel Vorlagen nicht datenbankübergreifend unterstützt werden da die Syntax der verschiedenen Datenbanktypen unterscheidlich ist. z.B. wenn sie eine Oracle Datenbank nach SQLite exportieren um diese im Feld mitzunehmen.
Nur ein Datenbank System = Keine Probleme
Wenn Sie nur ein Datenbanksystem benutzen, dann haben Sie keine Probleme. Verwenden Sie dann einfach die jeweilige Datenbank spezifische SQL Syntax.
Wann muss ich aufpassen?
Sobald sie Datenbankübergreifende Konfigurationen nutzten.
Beispiel 1 - Auskunftsdatenbank
Sie haben eine Oracle Datenbank und exportieren diese als SQLite um sie ohne Internetverbindung auf einem lokalen Rechner in den Aussen Dienst mit nehmen wollen.
In ihren Generic Dialoge haben Sie z.B. diverse SQL Labels eingebaut. Diese SQLs funktionieren, da sie fuer Oracle erzeugt wurden nun möglicherweise nicht im Zusammenhang mit SQLite. Das gleiche für Suchen, Darstellungsmodele, VB Scripte etc etc.
Beispiel 2 - Internetauskunft
Sie wollen eine Web Auskunft aufsetzten. Dies soll auf einem separaten eigenen Rechner geschehen der nicht mit dem Intranet verbunden ist. D.h. Sie exporteiern Oracle nach Postgres oder SQLite.
Beispiel 3 - Datenmigration
Sie haben beschlossen von Oracle nach Postgres zu migrieren.
Automatisches übersetzen von SQLs
ANSI SQL ist eine SQL Syntax und Funktionen die (laut Theorie) mit allen Datenbank typen funktionieren sollte. ANSI SQL unterstützt jedoch nur einen minimalen Funktionsumfang.
Oracle, Postgre und SQLite haben jeweils eigene SQL Dialekte und Funktionen. D.h. ein SQL der mit Oracle funktioniert muss nicht zwangsläufig mit Postgres oder SQLite und umgekehrt funktionieren.
Teilweise haben die gleichen SQL Funktionen in den verschiedenen Datenbanken andere Namen, andere Parameter oder auch andere Parameter Reihenfolgen.
Um diese Problem zu lösen wandelt MapEdit intern automatisch immer bei NICHT Oracle Datenbanken wie Postgres, SQLServer oder SQLite den SQL in einen SQL um der mit der jeweiligen Datenbank kompatibel ist.
D.h. man kann egal ob man Oracle, Postgres, SQLServer oder SQLite verwendet, bei allen Datenbanktypen die Oracle SQL Syntax/Funktionen verwenden.
Dadurch wird Mehrfachkonfiguration und Lernaufwand minimiert.
Dies funktioniert für die meist benutzten SQL Funktionen (also 90%).
Dadurch funktionieren 90% der SQLs Datenbank unabhängig ohne das die SQLs für jede Datenbank einzeln nachträglich angepasst werden müssen wenn man z.B. von Oracle nach Postgres wechselt oder SQL in Formularen oder anderen Stellen bereits verwendet und diese nicht alle anpassen will.
Dieser Mechanismus steht in MapEdit Mobile zur Zeit nicht zur Verfügung.
MapEdit wandelt nur von Oracle Syntax/Funktionen in die Sytnax der anderen Datenbank Typen um, nicht in anderer Richtungen. Wenn Sie z.B. Postgres Syntax/Funktionen verwenden, werden diese nicht nach Oracle oder SQLite umgewandelt.
Bei Benutzung von SQL Funktion dürfen zwischen dem Funktionsnamen und der Klammer keine Leerzeichen oder anderer Zeichen stehen.
Falsch:
TO_CHAR (fid)
Richtig:
TO_CHAR(fid)
JOINS mit (*)
können nur in Oracle verwendet werden.
MapEdit kann diese nicht automatisch in die jeweiligen Datenbank Dialekte übersetzen.
Verwenden Sie statt Oracle spezifischen (*)
JOINS immer ANSI SQL Join Anweisungen.
Automatisches übersetzen eines SQLs verhindern
Wenn man will das MapEdit den SQL nicht automatisch übersetzen soll, dann kann ganz hinten im SQL folgendes angeben.
--NOSIM
Dies steht für "No Simulation"
TRANSLATE
Im SQL Query Tool des AppBuilders gibt es eine Funktion TRANSLATE.
Mit dieser Funktion kann man sich anschauen nach was MapEdit einem SQL fuer die jeweilige Datenbank umwandelt.
Beispiel:
translate SELECT a.fid FROM table1 a, table2 b
WHERE SDO_RELATE(a.geom, b.geom, 'mask=ANYINTERACT')= 'TRUE'
Ergibt folgende Ausgabe:
Postgre SQL:
SELECT a.fid FROM table1 a, table2 b
WHERE upper(cast((ST_Intersects(a.geom,b.geom)) as text)) = 'TRUE'
SQLite SQL:
SELECT a.fid FROM table1 a, table2 b
WHERE SDO_RELATE(a.geom, b.geom, 'mask=ANYINTERACT') = 'TRUE'
SQLServer SQL:
SELECT a.fid FROM table1 a, table2 b
WHERE SDO_RELATE(a.geom, b.geom, 'mask=ANYINTERACT') = 'TRUE'
Sprich wenn man in MapEdit irgendwo eingibt:
SELECT a.fid FROM table1 a, table2 b
WHERE SDO_RELATE(a.geom, b.geom, 'mask=ANYINTERACT')= 'TRUE'
wird wenn dies auf einer Postgre DB ausgefuehrt wird dann im Hintergrund das hier ausgefuehrt
SELECT a.fid FROM table1 a, table2 b
WHERE upper(cast((ST_Intersects(a.geom,b.geom)) as text)) = 'TRUE'
SQLite unterstützt von sich aus keine Spatial funktionen. Es gibt ein OpenSource Modul namens Spatialite. Die wird in MapEdit nicht verwendet da dies grosse Probleme machte. Alle Spatial funktionen die mit MapEdit vewerndet werden sind Eigenimplementierungen.