Browsing "Older Posts"

Oracle Spatial (Teil 1) - Mein erster Tag

Von Tobias Arnhold → 9.11.2015
Ich habe in der Oracle DB Welt viele Themenkomplexe kennengelernt und mit gearbeitet. Eines ist bisher außen vor geblieben: Oracle Spatial mit dem Datentyp SDO_GEOMETRY

Warum?
Es hat sich wohl einfach noch nicht ergeben.
Aber irgendwann ist ja immer das erste Mal! :)

Heute habe ich die Aufgabe erhalten bestehende Koordinatendaten (X,Y) in das SDO_GEOMETRY Format GK3 zu transformieren.

Was wusste ich bisher?
Der SDO_GEOMETRY Datentyp wird über ein gesondertes Schema bereit gestellt:
MDSYS
Der Datentyp besteht aus X,Y und Z Koordinaten. Außerdem gibt es unterschiedliche Typen: Punkte, Linien, Objekte... Und anscheinend auch unterschiedliche Arten das Koordinatensystem (WGS 84, Gauss-Kruger 3) abzubilden.

Wie war mein Vorgehen um möglichst schnell Wissen zu erlangen?
Ich habe mich mit dem Datentyp auseinander gesetzt und bin dabei auf die genaue Datentyp-Definition gestoßen (Spatial User's Guide and Reference 10gR2 - 2 Spatial Data Types and Metadata):
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER,
SDO_SRID NUMBER,
SDO_POINT SDO_POINT_TYPE,
SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY,
SDO_ORDINATES SDO_ORDINATE_ARRAY
);

Der SDO_GTYPE definiert den Typ des Objekts: Punkt, Linie, Polygon,...
Info: Die folgende Tabelle zeigt die möglichen Typen und beschreibt die genaue Definition: http://docs.oracle.com/cd/B19306_01/appdev.102/b14255/sdo_objrelschema.htm#g1013735

Die SDO_SRID definiert das Koordinatensystem (WGS84, GK3, Arc 1950)
Info: Mit der folgenden Abfrage können Sie die verschiedenen System auslesen:
select srid,cs_name 
from cs_srs 
-- where srid in (31467, 8307, 8199);

Der SDO_POINT definiert die Koordinaten des Objekts.

SDO_ELEM_INFO und SDO_ORDINATES habe ich an meinem ersten Tag mit Oracle Spatial nicht verwendet. :P

Nun stellte sich die Frage, wie ich die Koordinaten aus meiner Testtabelle in den SDO_GEOMETRY Datentyp umwandeln kann? 
Bei der Suche bin ich auf den hervorragenden deutschsprachigen Blog gelandet:
http://oracle-spatial.blogspot.de

Und habe die passenden Antworten in dem Blogpost gefunden:
http://oracle-spatial.blogspot.de/2010/09/gauss-kruger-epsg-oder-nicht-epsg-das.html

Die Antwort war viel einfacher als gedacht:
SELECT 
  ADRESSE,
  GEO_KOORDINATE_X,
  GEO_KOORDINATE_Y,

  SDO_CS.TRANSFORM( 
    MDSYS.SDO_GEOMETRY (
      2001, -- Zweidimensionaler Punkt
      8307, -- Typ: WGS84
      SDO_POINT_TYPE(
          X => TO_NUMBER(GEO_KOORDINATE_X),  -- Längengrad / Longitude / Ost
          Y => TO_NUMBER(GEO_KOORDINATE_Y),  -- Breitengrad / Latitude / Nord
          Z => NULL
      ), 
      NULL,
      NULL
    ),
   31467 -- Umwandlung in GK3
   ) AS GEOMETRY_GK3

FROM MEINE_GEO_DATEN
Da mein Problem gelöst war, konnte ich ja Feierabend machen.
Hmm... woher weiß ich eigentlich, dass die Ergebnisse stimmen?

Hier liefert der SQL Developer die passende Lösung.
Der hat nämlich eine simple Geodatenanzeige integriert.

Außerdem liefert Oracle eine Geodaten-DB zum testen aus:
http://www.oracle.com/technetwork/database/options/spatialandgraph/downloads/navteq-data-download-2577974.html

Diese habe ich zum verifizieren meiner Ergebnisse direkt mal importiert und meine virtuelle Umgebung gesprengt, da die DB über 20GB groß wurde. :)

Dennoch konnte ich ein paar Interessante Tabellen importieren:
 - MAP_WORLD (Länderdarstellung - Flächen)
 - NTC_MAP_POI_CITY_CENTER (Städte mit Einwohnerzahlen - Punkte)

Diese habe ich dann in meine "Grafische Ansicht" integriert:


SELECT - Europa - Länderflächen:
SELECT
  COUNTRY,
  sdo_cs.transform(
    GEOMETRY,
    8307 -- Transformation in WGS84 notwendig
  ) as GEOMETRY FROM MAP_WORLD
where continent = 'Europe';

SELECT - Deutschland - Städte:
SELECT
  GEOMETRY,
  name
FROM NTC_MAP_POI_CITY_CENTER
where population > 30000
and iso_country_code = 'DEU';

SELECT - Meine Objekte:
SELECT
  GEO_WGS84,
  NAME
FROM MEINE_GEO_DATEN;

Und hier das Ergebnis:

Imho:
Innerhalb eines Tages kann man in einem ganz offensichtlich hochkomplexen Themengebiet, doch ganz beachtliche Ergebnisse erzielen.

Unterschiedliche Wege um APEX Anwendungsparameter zu setzen

Von Tobias Arnhold → 9.10.2015
Viele APEX Anwendungen benötigen zur korrekten Ausführung User-spezifische nicht veränderbare Variablen. Auf diese Variablen bezieht man sich, um sicherheitsrelevante Abfragen für den angemeldeten User auszuführen.

Hier eine kurze Liste an möglichen Anwendungsfällen:
- User ID
- User basierte Parameter
  (Land / Region / Ort / Niederlassung / Firmen- und Anwendungsspezifische Hintergründe)
- Rechte und Rollen
- Berechtigungen auf Zeilenebene
- Schreib- und Leserechte

Diese Variablen sollten je nach Inhalt und Verwendung auf eine der folgenden Arten gespeichert werden:
- APEX Application Items (Mit Protection Level: Restricted - May not be set from browser)
- APEX Collections (Eine Zeile)
- Eigene User- und Session spezifische Tabelle

Hinweis:
Die genannten Inhalte sollten nicht in Page-Items abgespeichert werden, auf diese Sie sich später beziehen.
Beispiel: P1_USER_ID

Die Vorteile ergeben sich wie folgt:
Application Items lassen sich leicht auslesen (Debugging) und verarbeiten (da diese immer pro Session gespeichert werden).

Collections und Custom-Tabellen haben erhebliche Performancevorteile bei Verwendung innerhalb von Datenbank-Views. Außerdem können mehr als 4000 Zeichen (CLOB) abgespeichert werden.
Beim Debugging und entwickeln (beispielsweise Views) sind eigene Tabellen (Imho) einfacher zu verarbeiten, dafür werden Collections automatisch pro Session angelegt und wieder gelöscht.

Was ist nun zu empfehlen?
Wenn die Größe einer Anwendung nicht feststeht oder es sich generell um eine kleine bis mittelgroße Anwendung handelt (10-60 Seiten), dann sollte man mit Application Items starten und im späteren Verlauf die Technik bei Notwendigkeit umstellen.
Wenn von vornherein klar ist, dass die Anwendung mehr als 100 Seiten groß wird und viele Nutzer mit vielen unterschiedlichen Attributen und Berechtigungen arbeiten, dann sind Collections oder eigene Tabellen zu bevorzugen.

Wie kann ein solcher Prozess aussehen?
Prinzipiell sollte ein solcher Prozess als "Application Process" angelegt sein. Außerdem sollte die komplette Logik in eine Package Prozedur ausgelagert werden und als Übergabeparameter den :APP_USER beinhalten.

Aufruf-Beispiel: 
APP_PACKAGE.START_APPLICATION (P_APP_USER => UPPER(:APP_USER));

Die Ausführung sollte dann nur einmal nach der Anmeldung geschehen:
Process Point: On New Instance (new session)
Info:
Hierbei hatte ich das ein oder andere Mal Probleme bei der korrekten Ausführung.
Daher ist alternativ auch eine PL/SQL Prüfung möglich:
:APP_USER <> 'nobody' and :AI_USER_ID IS NULL

Hinweis:
Achten Sie innerhalb ihrer Package Prozedur darauf, dass Sie Fehler in eine entsprechende Fehlertabelle wegschreiben.

Code Beispiel zum setzen der User ID:
-- ID auslesen
SELECT ID 
INTO V_USER_ID 
FROM MY_USER_TABELLE 
WHERE UPPER(USER_NAME) = P_APP_USER;
 

-- Item setzen
APEX_UTIL.SET_SESSION_STATE (
        P_NAME => 'AI_USER_ID',
        P_VALUE => V_USER_ID

);

Komplettes Beispiel:
Zentraler - Application Process

Package Prozedur:
Basierend auf einem alten Package-Beispiel, könnte der Code wie folgt aussehen:
create or replace package body pkg_login_example as
/* Package Variables */
  gv_proc_name    varchar2(100);
  gv_action       varchar2(4000);
  gv_ora_error    varchar2(4000);
  gv_custom_error varchar2(4000);
  gv_parameter    varchar2(4000);
  -- Globale User-Variable direkt im Package, Übergabeparameter ist so nicht notwendig
  gv_user         varchar2(20) := upper(nvl(v('APP_USER'),user));
  
/* Save errors */
/*
  --------------------------------------------------------
  --  DDL for Table ERR_LOG
  --------------------------------------------------------

  CREATE TABLE "ERR_LOG" 
   ( 
    "PROC_NAME" VARCHAR2(200), 
     "ACTION" VARCHAR2(4000), 
     "APP_ID" NUMBER, 
     "APP_PAGE_ID" NUMBER, 
     "APP_USER" VARCHAR2(20), 
     "ORA_ERROR" VARCHAR2(4000), 
     "CUSTOM_ERROR" VARCHAR2(4000), 
     "PARAMETER" VARCHAR2(4000), 
     "TIME_STAMP" DATE
   ) ;
/

*/
procedure add_err  is
pragma autonomous_transaction;
begin
     insert
     into err_log
      ( proc_name,action,app_id,app_page_id,app_user,ora_error,custom_error,parameter,time_stamp )
      values
      ( gv_proc_name,gv_action,nvl(v('APP_ID'),0),nvl(v('APP_PAGE_ID'),0),nvl(nvl(v('APP_USER'),user),'Unknown'),
        gv_ora_error,gv_custom_error,gv_parameter,sysdate );
     commit;
end;


/* ************************************************************************************************************************************** */
/* Anwendungsparameter zu setzen                                                                                                          */  
/* ************************************************************************************************************************************** */

procedure start_application
is
  v_user_id    my_user_table.id%type;
  v_user_role  my_user_table.user_role%type;

begin
  gv_proc_name := 'pkg_login_example.start_application';
  gv_parameter := '';
  
  gv_action := '1. Get USER_ID'; 
  select id 
  into v_user_id 
  from my_user_table
  where upper(user_name) = gv_user; 

  apex_util.set_session_state (p_name => 'AI_USER_ID',p_value => v_user_id);
  
  gv_action := '2. Get USER_ROLE'; 
  select user_role 
  into v_user_role
  from my_user_table
  where upper(user_name) = gv_user; 
  
  apex_util.set_session_state (p_name => 'AI_USER_ROLE',p_value => v_user_role);
  
  gv_action := '3. Get REGION_ROLES or whatever'; 
  -- ...
  
  commit;
exception
when others then   
      gv_ora_error := sqlerrm;
      gv_custom_error := 'Internal Error. Action canceled.';
      rollback;
      add_err; raise_application_error(-20001, gv_custom_error);
end;
 
end pkg_login_example;


APEX Connect 2015 - Review

Von Tobias Arnhold → 6.13.2015
Die APEX Connect 2015 (#apexconnect15) war die erste ihrer Art in Deutschland. Eine Konferenz bei der es nur um Oracle APEX ging.


Das waren die Fakten:
 - 2 Tage voll gepackt mit Themen rund um Application Express
 - 4 Vortragsstreams
 - Die Konferenz war ausverkauft (rund 250 APEX Enthusiasten)
 - TOP Developer aus dem In- und Ausland

Was sind die Eindrücke die ich mitnehme?
 - Die Organisation rund um das Event war TOP
 - Die technischen Möglichkeiten vor Ort waren angemessen
 - Networking zu jeder Zeit in sehr hoher Qualität möglich (In den Pausen, Während der Vorträge, bei der Abendveranstaltung)
 - Viele bekannte Gesichter und umso mehr Neue die ich mir nun einprägen muss. :)
 - Alle Vortragenden haben alles gegeben, wenngleich die Qualität doch variiert hat
 - Wo war Joel?

Meine persönlichen Highlights:
Ich selbst habe natürlich auch einen Vortrag zum Thema "Plug-Ins maßgerecht verwenden" gehalten. Wobei die Konkurrenz mit einem Parallelvortrag von Shakeeb Rahman zum Thema "Universal Theme" natürlich extrem hoch war. So muss es auch sein, ich war ja schließlich auf der APEX Connect und nicht auf der DOAG bei der es nur einen APEX Track gibt. ;)

Am Abend hatte ich dann die Ehre den ersten APEX Community Award an Carsten Czarski zu vergeben. Eine Tradition die nur der Anfang sein kann.

Ré­su­mé:
Ein perfekter Start mit viel Qualität und Spaß. Ich werde dieses Event so schnell nicht vergessen.

Wie gehts weiter?
Das nächste Großereignis wäre dann die DOAG 2015 in Nürnberg.
Nächstes Jahr zieht die APEX Connect von Düsseldorf nach Berlin (7. bis 9. Juni 2016). Ich bin gespannt ob wir da 400er Marke knacken! :)

Ps.:
Hier sind die Bilder zur Veranstaltung: apex.doag.org und die offizielle DOAG Review




APEX Connect Vortrag: Plug-Ins maßgerecht verwenden

Von Tobias Arnhold → 6.07.2015
SAVE THE DATE: Am Dienstag dem 09.06. zwischen 11:00 - 11:45 halte ich meinen Vortrag.

Wie so oft habe ich auch für diesen Vortrag eine individuell zusammengestellte APEX Anwendung entwickelt, anhand dessen ich die Präsentation halten werden.

Zusammengefasst:
#NOPOWERPOINT, #APEXONLY, #APEXPLUGINS

Der Vortrag eignet sich für Einsteiger wie Fortgeschrittene. Ich werde anhand unterschiedlichster Plug-Ins auf die Vorteile und Gefahren aufmerksam machen.

Also schaut rein und genießt die Show! :)

Ps.: Für Alle die nicht warten können, hier schon mal zwei Screenshots von der Anwendung:
 



APEX 5 New Feature Kurs

Von Tobias Arnhold → 5.14.2015
Vom 01.06. bis zum 02.06. wird es in der nähe von Frankfurt den wohl ersten APEX 5 New Feature Kurs in Deutschland geben.

Wer Interesse an den APEX 5 Neuerungen hat und schon bald eine Migration plant, der sollte sich jetzt noch schnell anmelden.


Ps.: Ich selbst werde auch eine Session zu APEX 5 Migrationen halten.

APEX im Jahr 2015

Von Tobias Arnhold → 4.20.2015
Mit dem erscheinen von APEX 5 dreht die Community jetzt so richtig auf.

Neben der APEX Connect im Juni (bis 08.05. Frühbucherrabatt) wird es schon einen Monat später eine Reihe von APEX 5 Webinaren unter dem Motto #apexsummer15 geben.



Was mir bei den ganzen Aktivitäten auffällt, ist der starke Community Faktor. Umso mehr wundert es mich, dass sich nach Veröffentlichung von APEX 5 keine große IT-News Plattform intensiver mit der Materie befasst hat. In Zeiten in denen über jeden noch so kleinen IT-Krümel geschrieben wird, verstehe ich es einfach nicht, wie man das Thema APEX komplett ignorieren kann. Sind die Medien erblindet? Haben Sie kein Interesse an Oracle, weil kein Open Source?

Imho: Was auch immer es ist, ich rate allen mal einen Blick auf die APEX Connect zu werfen und vor Ort selbst Teil dieser großartigen Community zu werden.

Ps.: Auf heise.de gab es eine kurze Meldung zum APEX 5 Release. Der Rest schweigt sich aus.

APEX 5.0 IST DAAAAAA!

Von Tobias Arnhold → 4.15.2015
Endlich ist es geschafft.

Wen interessiert Heute die Champions League, wenn du Oracle APEX 5 downloaden kannst:
http://www.oracle.com/technetwork/developer-tools/apex/downloads/index.html