APEX

Aus XmasWiki
Wechseln zu: Navigation, Suche

Verwendung der Programmiersprache plsql.

Inhaltsverzeichnis

Literatur

Pro Oracle Application Express

Versionen

  • 3.1.2.00.02 => API 2007.01.08
  • 3.2.1.00.12 => API 2009.01.12
  • 4.0.1.00.03 => API 2010.05.13
  • 4.1.0.00.32 => API 2011.02.12
  • 4.2.2.00.11 => API 2012.01.01
  • 4.2.3.00.07 => API 2012.01.01

Version abfragen:

select comp_name, version from dba_registry where comp_name = 'Oracle Application Express';

oder

select * from apex_release;

Installation

APEX (Application Express) ist ein auf der Oracle Datenbank aufgesetzte, webbasierte Anwendung, welche mittels Apache Webserver die Möglichkeit bietet ähnlich wie mit PHP Internetseiten zu definieren. Dabei hat APEX den Vorteil, dass ein ganzes Framework zur Verwaltung und Erstellung der Seiten vorhanden ist. Trotzdem bleibt das System so offen, dass man alle Möglichkeiten besitzt um Internetanwendungen zu erstellen.
Vorteil dabei ist, dass man die Anwenhttp://wiki.xmasman.de/index.php?title=ApexVersionen&action=editdungen einerseits sehr schnell und einfach ohne weitere Tools per Webbrowser entwerfen kann und direkt an eine Datenbank angebunden ist. Durch die enorme Fülle von Templates, Vorlagen und der guten Bearbeitungsmöglichkeit kann Seiten erheblich schneller erstellen und gestalten wie mit jeder mir bekannten anderen Programmiersprache.
Mittlerweile (24.03.2009) ist APEX in Version 3.2. Apex Versionsübersicht

Oracle Express Edition (XE) - Installation unter Debian / Ubunto

Entsprechend dieser Dokumentation installierbar.

In der Datei

/etc/apt/sources.list 

die Zeile

deb http://oss.oracle.com/debian unstable main non-free

Danach noch diesen Link als autorisierten Link von Oracle einfügen mittels diesen Befehlen:

wget -q http://oss.oracle.com/el4/RPM-GPG-KEY-oracle
gpg --import RPM-GPG-KEY-oracle
gpg --fingerprint build@oss.oracle.com
gpg --armor --export B38A8516 | apt-key add -

Und dann einmal apt-get update aufrufen.

Nun mittels

aptitude install oracle-xe-universal 

das ganze installieren. Dabei werden 262 MB runtergeladen und es wird das libaio Package nach Bestätigung mit runtergeladen.

  • Falls keine 1GB große Auslagerungsdatei vorhanden ist muss diese folgendermaßen angelegt werden:

dd if=/dev/zero of=/swapfile bs=1M count=1000
mkswap /swapfile
swapon /swapfile


Bei der Installation werden dann Port der Datenbank(1521) und der Webadresse(8080) abgefragt, welche für Testsysteme so bleiben können. Das Passwort dann am besten notieren.
Wenn alles glatt gelaufen ist sollte man nun unter der lokalen Maschine (also nur von dem Rechner aus selber) den Server unter http://localhost:8080/apex erreichen können. Will man von einer anderen Maschine zugreifen muss man dies erst in der Datenbank aktivieren.
Zuerst als root einloggen über ssh. Danach mit dem Befehl su - oracle auf den Oracle User wechseln. Jetzt muss man die Umgebungswerte für diesen User setzen mit dem Befehl:

su - oracle
. /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh
sqlplus /nolog
conn sys/passwort@xe as sysdba
EXEC DBMS_XDB.SETLISTENERLOCALACCESS(FALSE);

Dabei sei noch erwähnt, das ich bisher keinen virtuellen Server gefunden habe wo dies möglich ist anzupassen. Daher geht eine XE Debian Installation wohl nur auf Rootserversystemen. Jetzt kann man sich unter http://serveradresse:8080/apex einloggen. Dabei muss man username SYSTEM und das Passwort verwenden was man bei der Installation verwendet hat.

Oracle Express Edition (XE) - Installation unter Windows XP / Vista / 7

  • Hier noch ein weitere recht aktueller Guide http://blog.oracleapex.at/installationsanleitung-fur-oracle-xe-oracle-apex-oracle-http-server/
  • Zuerst muss man unter folgendem Link die Installationsdatei runterladen:
    http://www.oracle.com/technology/software/products/database/xe/index.html
    Dort sollte man Universal wählen da diese Installation alle Sprachen in der Datenbank unterstütz, als auch eine deutsch Oberfläche bietet.
  • Man führte die *.exe Datei aus und man benötigt mindestens 1.5GB für das gesamte System (mit Update auf 3.0.1). Dabei gibt man bei der Installation neben dem Installationsverzeichnis auch das MasterPasswort an. (Bei Oracle gilt dies für den User sys oder auch system) Die Installation dauert einige Zeit (ca. 10Minuten sollte man einplanen).
  • Nach der fertigen Installtion kann man im Browser einfach http://localhost:8080/apex eingeben und sollte die Startseite von APEX zu Sehen bekommen. Dort kann man sich nun mit SYSTEM und dem bei der Installation eingegebenen Passwort anmelden.
  • Für den Zugriff von außen (also von einem anderen Rechner als dem eigenen) muss man noch folgende Einstellung machen: Einfach die Commandozeile aufrufen (unter Windows -> Start -> Ausführen -> cmd.exe):

sqlplus /nolog
SQL>conn sys/passwort@xe as sysdba
SQL>exec dbms_xdb.setlistenerlocalaccess(false);

Oracle Application Express unter DB 11

Zugriff mit XDB / XMLDB

  • Unter 11g ist APEX wie in der Express Edition direkt über die XMLDB zu betreiben. Man muss dabei lediglich in der Datenbank APEX aktivieren.
  • Dazu als Oracle User in das $ORACLE_HOME/apex Verzeichnis wechseln. Dann zur Datenbank verbinden und das Konfigurationsscript aufrufen und den User Anonymous entsperren und den Zugriff außerhalb von freischalten.

sqlplus /nolg
SQL>conn sys as sysdba
SQL>@apxconf
SQL>alter user anonymous account unlock;
SQL>exec dbms_xdb.setListenerLocalAccess(false);

Linux mit Apache (ohne XML-Gateway)

Anleitung Oracle HTTP Server http://download-east.oracle.com/docs/cd/B14099_19/web.1012/b14009/toc.htm
Für bestimmte Zwecke kann es nötig sein, dass man doch die Benutzung über den Apache Webserver benötigt dazu findet man weitere Infos unter: Apache anstatt XML Gateway. Der Download dafür ist Oracle Apache 2.x. Dazu muss man sich auf dem Betriebssystem aber über eine grafische Oberfläche einloggen können um den Installer auszuführen. Die Anleitung dazu ist auch nochmal dort: Configuring Oracle HTTP Server 11g or Oracle Application Server 10g. In kürze bedeutet das:

  • zuerstOracle Apache 2.x runterladen (sollte dem user oracle:oinstall gehören)
  • entpacken mit

unzip as_101330_apache2_lnx.zip -d ./as_101330_apache2_lnx

  • jetzt als root die grafische Oberfläche mittels zur Verfügung stellen: DISPLAY=:0.0; export DISPLAY und

xhost +

    • falls man über vnc eingeloggt ist muss der Aufruf so sein: DISPLAY=:13; export DISPLAY und xhost +
    • man kann das ganze auch so schreiben: export DISPLAY=:13
  • environment datei anpassen oder ggf. erstellen mit:

NLS_LANG=AMERICAN_AMERICA.AL32UTF8

  • nun wieder als oracle (environment ggf. laden) und installer ausführen ./runInstaller
    • während der Installation wird man um Ausführung eines Scriptes unter root gebeten dies entsprechend ausführen und danach auf ok klicken. Dabei belässt man das bin directory auf /usr/local/bin und überschreibt die 3 Einträge für dbhome, oraenv und coraenv in /usr/local/bin
    • ggf. (unter SUSE EL 10 zum Beispiel) benötigt man weitere Libraries. Dies muss man hier überprüfen und dann ggf mit Links sich behelfen: ln -s libgdbm.so.2 libgdbm.so.3 und ln -s libdb-4.3.so libdb-3.3.so Das ganze kann man im Metalink auch unter dem Topic (Oracle HTTP Server Unable To Start Due To Missing Libraries libdb-3.3.so libgmv ./dbm.so.2) finden (Topic 735605.1).
      • Bei RHEL 5.5 fehlende installieren

yum install libgdbm.so.2

und mittels

ln -s /usr/lib/libdb-4.3.so /usr/lib/libdb-3.3.so

  • jetzt sollte der Webserver unter http://localhost:7777 oder http://localhost:7780 (für localhost die entsprechende Adresse) erreichbar sein. Von außen sollte der entsprechende Port in der Firewall freigeschaltet werden.
  • danach die dads.conf anpassen (vorher einmal Datei sichern), befindet sich in /u01/app/oracle/ohs/modplsql/conf/dads.conf
    • dafür Zugriffswerte aus der listener.ora übernehmen (%ORACLE_HOME%/network/admin/listener.ora)
    • /u01/app/oracle/ohs/ohs/modplsql/conf/dads.conf

Alias /i/ "/u01/app/oracle/apex_images/"
AddType text/xml       xbl
AddType text/x-component       htc
<Location /pls/apex>
 Order deny,allow
 PlsqlDocumentPath docs
 AllowOverride None
 PlsqlDocumentProcedure      wwv_flow_file_manager.process_download
 PlsqlDatabaseConnectString  db11g:1521:db11g ServiceNameFormat
 PlsqlNLSLanguage            AMERICAN_AMERICA.AL32UTF8
 PlsqlAuthenticationMode     Basic
 SetHandler                  pls_handler
 PlsqlDocumentTablename      wwv_flow_file_objects$
 PlsqlDatabaseUsername       APEX_PUBLIC_USER
 PlsqlDefaultPage            apex
 PlsqlDatabasePassword       <PASSWORD>
 Allow from all
</Location>

  • APEX_PUBLIC_USER überprüfen ggf unlocken
    • select USERNAME,ACCOUNT_STATUS from dba_users where USERNAME = 'APEX_PUBLIC_USER';
    • alter user APEX_PUBLIC_USER account unlock;
    • Und vielleicht das Passwort setzen falls unbekannt: alter user APEX_PUBLIC_USER identified by passwort;
      • entsprechend die Grafiken wie angegeben in den htdocs ordner kopieren order als Softlink verlinken. Zum Beispiel nach: /u01/app/ohs/htdocs/apex/images oder Link anlegen ln -s /home/oracle/apex_4.0.2/apex/images /u01/app/oracle/apex_images und dann entsprechend in der dads.conf einstellen.
  • webserver restarten /u01/app/oracle/ohs/opmn/bin/opmnctl restartproc ias-component=HTTP_Server oder opmnctl stopall und startall
  • Nun sollte Apex über http://localhost:7780/pls/apex erreichbar sein.

Windows mit Apache (ohne XML-Gateway)

Anleitung Oracle HTTP Server http://download.oracle.com/docs/cd/B32110_01/index.htm
Für bestimmte Zwecke kann es nötig sein, dass man doch die Benutzung über den Apache Webserver benötigt dazu findet man weitere Infos unter: Apache anstatt XML Gateway. Der Download dafür ist Oracle WebCenter 10g Microsoft Windows. Dazu muss man sich auf dem Betriebssystem aber über eine grafische Oberfläche einloggen können um den Installer auszuführen. Die Anleitung dazu ist auch nochmal dort: Configuring Oracle HTTP Server 11g or Oracle Application Server 10g. In kürze bedeutet das:

  • zuerstOracle WebCenter 10g runterladen
  • dann die Datei entpacken (Verzeichnis ist egal)
  • nun den Installer starten mit Klick auf die Setup.exe
    • oben zuerst den Pfad eingeben worunter die Installation stattfinden soll.
    • Nun erweiterte Installation auswählen
    • Installationsart -> Oracle HTTP Server (371MB)
    • Port Konfiguration -> automatisch
    • Instance-Name -> orcl_http_10g (zum Beispiel)
    • Cluster -> nichts auswählen
    • Überblick -> Installation bestätigen
    • Ende der Installation -> Inhalt evtl. notieren bzw. Serveradresse http://localhost:7777
  • danach die dads.conf anpassen (vorher einmal Datei sichern), befindet sich in C:\oracle\product\10.1.3.2.0\OracleAS_1\Apache\modplsql\conf\dads.conf
    • dafür Zugriffswerte aus der listener.ora der entsprechenden Datenbank übernehmen (%ORACLE_HOME%/network/admin/listener.ora)
    • Alias /i/ "C:\oracle\product\10.1.3.2.0\OracleAS_1\Apache\Apache\htdocs\images_apex312/"
      AddType text/xml xbl
      AddType text/x-component htc

      <Location /pls/apex>
      Order deny,allow
      PlsqlDocumentPath docs
      AllowOverride None
      PlsqlDocumentProcedure wwv_flow_file_mgr.process_downloadd
      PlsqlDatabaseConnectString host:port:service_name ServiceNameFormat
      PlsqlNLSLanguage AMERICAN_AMERICA.AL32UTF8
      PlsqlAuthenticationMode Basic
      SetHandler pls_handler
      PlsqlDocumentTablename wwv_flow_file_objects$
      PlsqlDatabaseUsername APEX_PUBLIC_USER
      PlsqlDefaultPage apex
      PlsqlDatabasePassword apex_public_user_password
      PlsqlRequestValidationFunction wwv_flow_epg_include_modules.authorize
      Allow from all
      </Location>
    • APEX_PUBLIC_USER überprüfen ggf unlocken
      • select USERNAME,ACCOUNT_STATUS from dba_users where USERNAME = 'APEX_PUBLIC_USER';
      • alter user APEX_PUBLIC_USER account unlock;
      • Und vielleicht das Passwort setzen falls unbekannt: alter user APEX_PUBLIC_USER identified by passwort;
      • entsprechend die Grafiken wie angegeben in den htdocs ordner kopieren. Zum Beispiel nach: C:\oracle\product\10.1.3.2.0\OracleAS_1\Apache\Apache\htdocs\images_apex312
  • webserver restarten C:\oracle\product\10.1.3.2.0\OracleAS_1\opmn\bin\opmnctl restartproc ias-component=HTTP_Server (oder stopall und startall)
  • Nun sollte Apex über http://localhost:7777/pls/apex erreichbar sein.

APEX installieren (4.0.2)

  • Installationsanleitung APEX 4.0
  • Vorversion raussuchen -> Bei Versionsänderung der ersten beiden Stellen, Komplettinstallation, ansonsten Teilupdate.
    • Für Komplettinstallation einfach auf apex.oracle.com gehen und entsprechend runterladen. Bei 4.0.2 ist dies apex_4.0.2.zip mit 139MB.
    • Für Teilinstallation unter metalink einloggen und nach Patchnummer suchen. Für 4.0.2 ist dies die Nummer 10173973 mit der Datei p10173973_112020_Generic.zip (55.8MB).

Vollinstallation

Voraussetzungen

  • Entpacken der Version, wobei es sich anbietet den Namen der SQL-Datei als Ordner zu nehmen (apex_4.0.2). Außerdem wird bei Rückführung eines Updates das Installationsverzeichnis der Vorversion wieder benötigt.
  • Als erstes muss für APEX 4 überprüft werden ob SHARED_POOL_SIZE mindestens 100MB hat (falls nicht entsprechend wie unten beschrieben erhöhen):

sqlplus /nolog
SQL> conn sys as sysdba
SQL> SHOW PARAMETER PFILE;
SQL> SHOW PARAMETER SHARED_POOL_SIZE
SQL> ALTER SYSTEM SET SHARED_POOL_SIZE='100M' SCOPE=spfile;
SQL> SHUTDOWN (oder bei Windows den Dienst OracleServiceORCL beenden und neu starten)
SQL> STARTUP

  • Folgender Tablespace wird benötigt: 185MB (SYSAUX oder entsprechend gewählter) und 100MB (SYSTEM)
  • Für die Suche muss Oracle Text aktiviert/installiert sein in der DB. Vorher in folgendes Verzeichnis wechseln: Windows: "c:\oraclexe\app\oracle\product\10.2.0\server\ctx\admin\defaults\" oder Linux: "/usr/lib/oracle/product/10.2.0/server/ctx/admin/defaults"

sqlplus /nolog
SQL> alter user ctxsys account unlock;
SQL> alter user ctxsys identified by <password>;
SQL> connect ctxsys 
SQL> @drdefus
SQL> connext sys as sysdba
SQL> alter user ctxsys account lock;

  • PL/SQL Web Toolkit mindestens in der Version 10.1.2.0.6 (untenstehende Abfrage bzw. Installationsdatei ausführen falls nötig, ins Verzeichnis "apex\owa" von der jeweiligen APEX Version gehen.):

sqlplus /nolog
SQL> conn sys as sysdba
SQL> select owa_util.get_version from dual;
SQL> @owainst.sql

Installation

  • Hier muss nun überlegt werden wie man den Server anspricht. Apache HTTP, APEX Listener oder PL/SQL Gateway. Installation der Datenbankdateien ist gleich, aber Bereitstellung der Links, Grafiken und weitere Einstellungen hängen davon ab.
  • Installationsaufruf bei dem die Schemata APEX_040000, APEX_PUBLIC_USER und FLOWS_FILES angelegt werden (aus Verzeichnis apex (apexins tablespace_apex tablespace_files tablespace_temp images)):

sqlplus /nolog
SQL>conn sys as sysdba
SQL>@apexins SYSAUX SYSAUX TEMP /i/

  • Falls Installation mit PL/SQL Gateway dann Grafiken über SQL kopieren (entsprechend Pfad anpassen). Falls die Installation von APEX ganz neu ist muss man das Script apex_epg_config ausführen (@apex_epg_config /verzeichnis_in_dem_der_entpackte_Ordner_APEX_liegt)

set NLS_LANG=American_America.AL32UTF8 oder bei Linux NLS_LANG=American_America.AL32UTF8 export NLS_LANG
sqlplus /nolog
SQL> conn sys as sysdba
SQL> @apxldimg.sql "d:\Eigene Dateien\APEX\apex_4.0.2" oder bei Linux @apxldimg /usr/lib/oracle/apex/apex_4.0.2

  • Falls die Vorversion sehr alt ist muss man den Adminaccount freischalten. Aus dem Verzeichnis /apex folgenden Aufruf machen.

sqlplus /nolog
SQL> conn sys as sysdba
SQL> @apxchpwd

Deutsches Sprachpaket

Zuerst wird das Charset korrekt eingestellt, damit die Scripte und Dateien keine Probleme mit Umlauten erzeugen

  • Linux

NLS_LANG=American_America.AL32UTF8
export NLS_LANG

  • Windows

set NLS_LANG=American_America.AL32UTF8

Danach dann ins Verzeichnis /apex/builder/de wechseln und das Datenbankscript aufrufen.

sqlplus /nolog
SQL> conn sys as sysdba
SQL> ALTER SESSION SET CURRENT_SCHEMA = APEX_040000;
SQL> @load_de

APEX installieren (3.2.1)

Apex 3.2 Install-Doku
Als nächstes muss man in der momentenen Version (bei XE ist die Version 2.1 installiert) noch APEX auf die aktuelle Version installieren (3.2, Stand 23.03.09). Generell ist es bei APEX so, dass ein Versionssprung in der ersten Ziffer vor oder nach dem Punkt immer ein neues Schema verwendet wird. Man installiert also bei allen Änderungen (X.Y.Z) wo sich X oder Y ändern APEX per Script komplett neu. Ändert sich nur Z (also nur die letzte Nummer) wird ein Patch über Metalink angeboten. Dabei geht man wie folgt vor:

  • Die Dateien dazu findet man hier: http://www.oracle.com/technology/products/database/application_express/download.html .Hier befinden sich immer komplette Versionen keine Patches. Ein komplettes Installationsscript ist momentan ca. 100MB als Zip-File.
  • Windows: Nachdem man das ganze runtergeladen hat entpackt man es und öffnet die Kommandozeile (Start -> Ausführen -> CMD eingeben).
    Linux: Mittels WinSCP auf den Server kopieren oder mit Browser runterladen. Danach in einem Verzeichnis mit unzip apex_3.2.zip entpacken (es wird ein Unterverzeichnis APEX erstellt). Man sollte dabei darauf achten alle folgenden Schritte mit User Oracle zu machen (su - oracle)
  • Jetzt geht man in das Verzeichnis in welches man die Dateien entpackt hat und geht dort in den Ordner apex. Dort sollten mehrere *.sql Dateien liegen. (Wie gesagt als oracle User in Linux)
  • Als nächstes muss man sich zur Datenbank verbinden und den Patch einspielen dazu führt man folgendes aus (Achtung bei der Zeile @apexins wird der Patch ausgeführt dies kann bis zu 10Minuten wieder dauern):

    sqlplus /nolog
    SQL>conn sys/sys_passwort@xe as sysdba
    SQL>@apexins SYSAUX SYSAUX TEMP /i/

    Falls es Probleme gibt mit dem Login kann es sein, dass der Admin Account gelockt ist. Dies kann man mittels des Scripts "apxxepwd.sql" wieder aufheben.

    sqlplus /nolog
    SQL>conn sys/sys_passwort@xe as sysdba

    SQL>@apxxepwd

    Falls weiterhin Probleme auftreten und das Passwort beim Login nochmal abgefragt wird zur Änderung, dies aber nicht korrekt klappt kann dieser Aufruf helfen:

    SQL>update apex_030200.wwv_flow_fnd_user set change_password_on_first_use ='N' where lower(user_name) = 'admin';

    SQL>commit;
  • Jetzt muss man die Grafiken aktualisieren. Dies muss nur gemacht werden wenn APEX ein neues Schema anlegt (oben erläutert). Bei 11g oder XE werden die Grafiken per Script folgendermaßen kopiert:

    sqlplus /nolog
    SQL>conn sys/sys_passwort@xe as sysdba
    SQL>@apxldimg c:\temp
    wobei der Ordner apex in c:\temp liegt (c:\temp\apex) oder unter unix halt (@apxldimg /home/oracle/apex_3.2) falls das Verzeichnis apex entsprechend dort liegt.

    Benutzt man einen Apache-Webserver oder das Script läuft nicht muss man die Grafiken von Hand in das Apache htdocs Verzeichnis kopieren oder per Webdav (bei 11g oder XE).
    Während man bei der Installation von APEX auf einem Applikation Server die Grafiken in das Verzeichnis des Apache kopiert, muss man bei der XE über WebDAV die Dateien auf den Server schieben.
    Dazu öffnet man den Explorer und klickt dort mit rechter Maustaste auf Netzwerkumgebung und danach folgendes:

      - Netzlaufwerk verbinden
      - Onlinespeicherplatz anfordern oder mit einem Netzwerkserver verbinden (nächste Seite weiter)
      - Eine andere Netzwerkressource auswählen ...
      - Folgende Adresse verwenden: http://127.0.0.1:8080 (oder entsprechende IP)
      - User system und das Passwort eingeben was man bei Installation von XE/11g angegeben hat. Danach nur Name angeben und fertigstellen
      - Nun nennt man das alte Verzeichnis der Grafiken um zum Beispiel in i_2_1
      - Man erstellt dann das Verzteichnis /i/ neu und kopiert aus dem Verzeichnis wo man die Dateien für APEX entpackt hat den gesamten Inhalt des Ordners /images/ in den neu erstellten Ordner /i/
  • Nun kann man sich auf http://localhost:8080/apex wieder einloggen und folgende Eingaben machen:

    Workspace: INTERNAL
    User: ADMIN
    Passwort: Passwort

Nun ist das System soweit auf dem neustem Stand und man kann mit dem Erstellen der Anwendungen loslegen.

Embedded Gateway Einstellungen abfragen

/u01/app/oracle/product/11.1.0/db_1/rdbms/admin/epgstat.sql

Teilupdate (3.1.1 -> 3.1.2)

Patch ausführen mit

@apxpatch

danach die Grafiken kopieren per Script (nur xe)

@apxldimg "c:\temp\patch"

Dabei am besten aus dem entsprechenden Ordner patch das Script ausführen und keine Leerzeichen im Pfad.

APEX Update/Version rückganging machen bzw. löschen

APEX 3.2.1 zu 2.1

Falls man nach einem Update Probleme hat ist ein Rückgängig machen dieses Updates kein Problem und Bedarf folgender Schritte:

  • Als erstes verbindet man sich zur Datenbank und aktiviert seine alte Version (hier 2.1):

sqlplus /nolog
SQL>conn sys/password@xe as sysdba ALTER SESSION SET CURRENT_SCHEMA = FLOWS_020100; exec flows_020100.wwv_flow_upgrade.switch_schemas('APEX_030200','FLOWS_020100');

Wichtig: bei den Versionen bis 3.1.2 ist das Schema immer FLOWS_XXXXXX, ab 3.2 wurde dies in APEX_XXXXXX geändert.

  • Als nächstes Entfernt man die alte Version:

DROP user APEX_030200 CASCADE;

Infos dazu hier: http://www.oracle.com/technology/products/database/application_express/install_faq.html#08

  • als letztes muss man noch das alte Grafikverzeichnis wieder in /i/ umbenennen und schon sollte alles wieder funktionieren

APEX 4.1.1 zu 3.2.1

In der Dokumentation zu finden unter: Oracle® Application Express Installation Guide
Ins Verzeichnis apex_3.2.1/apex/core wechseln und folgendes ausführen:

sqlplus /nolog
SQL>conn sys as sysdba @wwv_flow_val.plb @wwv_dbms_sql.sql @wwv_dbms_sql.plb

danach ins Verzeichnis apex_3.2.1/apex wechseln und folgendes ausführen:

sqlplus /nolog
SQL>conn sys as sysdba @apexvalidate x x APEX_030200 ALTER SESSION SET CURRENT_SCHEMA = APEX_030200; exec apex_030200.wwv_flow_upgrade.switch_schemas('APEX_040100','APEX_030200'); ALTER SESSION SET CURRENT_SCHEMA = SYS; exec validate_apex;

jetzt noch APEX 4.1.1 löschen

sqlplus /nolog
conn sys as sysdba
DROP USER APEX_040100 CASCADE;

Deutsches Sprachpaket installieren

Linux

verbinden per ssh als root (oder direkt als oracle dann ohne su - oracle)

su - oracle
. oracle_env.sh
NLS_LANG=American_America.AL32UTF8
/.../apex_4.0.2/apex/builder/de
sqlplus /nolog
SQL> conn sys as sysdba
SQL> ALTER SESSION SET CURRENT_SCHEMA = APEX_040000;
SQL> @load_de

Windows

Unter Windows Kommandozeile starten

set NLS_LANG=American_America.AL32UTF8
c:\...\apex_4.0.2\apex\builder\de
sqlplus /nolog
SQL> conn sys as sysdba
SQL> ALTER SESSION SET CURRENT_SCHEMA = APEX_040000;
SQL> @load_de

Oracle 11g mit APEX Installation auf Windows XP / Vista

Zuerst Datenbank runterladen http://www.oracle.com/technology/software/products/database/index.html
Danach diese Anleitung zur Aktivierung von APEX http://www.oracle.com/technology/obe/11gr1_db/install/apexinst/apexinst.htm
Generell sei erwähnt, dass in der 11g die Installation und vor allem die Bilder wie bei XE kopiert werden und man keinen separaten Apache benötigt. Man aktiviert lediglich APEX per Script.

Gateways zu APEX

OHS - Oracle HTTP Server

Web Tier Utilities (11.1.1.3.0) => ausklappen, dort steht der HTTP Server. Jeweilige Version für Windows/Linux 32/64 Bit runterladen.

EPG - embedded PL/SQL Gateways

APEX Listener

Starten & Stoppen

Linux

  • Anmelden als Oracle User
  • Terminal öffnen (bei Redhat rechtsklick auf Desktop und Terminal ausführen)
  • Environment setzen

. oraenv

    • Abfrage der SID entsprechend beantworten beispiel: db11g. Danach sollte das Oracle Home ausgegeben werden.
  • Listener starten:

lsnrctl start

  • Datenbank starten

sqlplus /nolog
SQL>conn sys as sysdba
SQL>startup

  • ggf. Apache Webserver / OHS (Oracle HTTP ServeR) starten
  • Neues Terminal und über opmnctl den Start als Oracle User ausführen.

/u01/app/oracle/ohs/opmn/bin/opmnctl startall

Windows

  • Listener sollte theoretisch als Dienst vorhanden sein, der entweder automatisch mitgestartet wird oder über Dienste gestartet werden kann.
  • Datenbank auch als Dienst starten. Sollte am besten nicht automatisch gestartet werden.
  • HTTP Server auch als Dienst starten.

Konfiguration

NTLM / Active Directory (AD) Authentication

  1. Find the file that contains the DAD description used for Application Express (most likely $OH/Apache/modplsql/conf/dads.conf)
  2. Edit the DAD entry for Application Express adding PlsqlCGIEnvironmentList AUTHORIZATION
  3. Save the file
  4. Stop and start Apache/ Oracle HTTP Server
  • Erstellung des Authentication Schemes
  1. Click Shared Components from the Application Builder home page
  2. Click Authentication Schemes under Security
  3. Click Create >
  4. Choose From scratch and click Next >
  5. Enter NTLM in the Name field and click Next >
  6. Enter return ntlm_page_sentry in the Page Sentry Function text area and click Next >
  7. Click Next > until the Confirm step
  8. Click Create Scheme
  9. Click Change Current
 10. Choose NTLM and Click Next >
 11. Click Make Current
  • Bei Internetexplorer muss die Sicherheitsstufe für das lokale Netz auf niedrig oder mittel gestetllt werden. Für Firefox folgende Einstellung
  1. Type about:config in the address bar
  2. Type ntlm in the filter text box
  3. Double click the preference network.automatic-ntlm-auth.trusted-uri's and enter a comma separated list of trusted servers on your network

We have investigated the issue and found a solution that you can use to enable SSO on windows 7 systems.
To do it, please go to Local Security policy > Security settings > local policies > security options
Select Network security > Lan manager Authentication level and change it to "Send LM & NTLM responses" 

apex_application.get_browser_version != 'MSIE' and owa_util.get_cgi_env('DAD_NAME') = '/pls/apex'

  • Code für Überprüfung des "Remote User" (REMOTE_USER hat auch die Domain bei der NTLM Authentifizierung enthalten "mt-ag.com\xname"

UPPER(owa_util.get_cgi_env('REMOTE_USER'))!= 'APEX_PUBLIC_USER' and  owa_util.get_cgi_env('DAD_NAME') = '/pls/apex' 

Kerberos Authentification

Installation

  • Anlegen eines Benutzers im Active Directory für den Zugriff von Apache aufs AD.
  • Erzeugen einer „keytab“-Datei, welche auf dem Apache Server unter /etc/kerberos/ abgelegt werden muss.
  • Anpassen der krb5.conf. Änderungen könnten so ca. aussehen:

[libdefaults]
default_realm = MT-AG.COM
clockskew = 900
[realms]
MT-AG.COM = {
kdc = server01.MT-AG.COM
}
[domain_realm]
.mt-ag.com = MT-AG.COM

  • Nun muss man im Apache in der httpd.conf das mod_auth_kerb Modul laden:

LoadModule auth_kerb_module libexec/mod_auth_kerb.so

  • Danach muss die marvel.conf / dads.conf (je nachdem wo die Konfiguration für APEX eingetragen ist) angepasst werden. Dies könnte so aussehen:

<Location /pls/apex>
Order deny,allow
PlsqlDocumentPath docs
AllowOverride None 
AuthType Kerberos
AuthName "Kerberos-Login"
KrbMethodNegotiate On
KrbMethodK5Passwd Off
KrbAuthRealms MT-AG.COM
Krb5KeyTab /etc/kerberos/APEX.keytab
require valid-user 
PlsqlDocumentProcedure wwv_flow_file_manager.process_download
PlsqlDatabaseConnectString db11g:1521:db11gutf8 ServiceNameFormat
PlsqlNLSLanguage AMERICAN_AMERICA.AL32UTF8
PlsqlAuthenticationMode Basic
SetHandler pls_handler
PlsqlDocumentTablename wwv_flow_file_objects$
PlsqlDatabaseUsername APEX_PUBLIC_USER
PlsqlDefaultPage apex
PlsqlDatabasePassword xxxx
Allow from all
</Location>

PDF-Printing

Im groben gibt es 2 Möglichkeiten PDF zu erzeugen. Einmal über den BI-Publisher welcher recht hohe Lizenzkosten benötigt, aber als Oracle Advanced Lösung direkt eingebunden werden kann. Dort sind komfortable und per Vorlage definierte Layouts möglich.
Die andere Möglichkeit ist über eine allgemeine XSLFO-Engine den Export zu genieren. Dabei sind weiter unten die Beispiel OC4J-Container und Cocoon + Tomcat erklärt. Beim OC4J Container sei noch erwähnt, dass auch dieser produktiv eingesetzt Lizenzkosten benötigt, nicht aber Cocoon zusammen mit Tomcat.

mit Javascript

http://www.cc13.com/wordpress_21/?p=310

... mit Apache Cocoon und Tomcat

Dies ist die einfachste Variante und dabei auch kostenlose Möglichkeit PDF zu erzeugen. Alle Infos dazu kann man hier finden: http://carlback.blogspot.com/2007/03/apex-cocoon-pdf-and-more.html und hier die Installationsanleitung : http://apex.oracle.com/i/carl/apex_cocoon/APEX_TOMCAT_COCOON_viewlet_swf.html
Das ganze ist wirklich super einfach und klappt perfekt. Dabei sollte man nur beachten, dass große grafische Anpassungen nicht möglich sind. Es werden dabei Exporte nach PDF und RTF ermöglicht.

... mit OC4J Container

Hier der offizielle Leitfaden zur Installtion von Oracle: http://www.oracle.com/technology/products/database/application_express/html/configure_printing.html
Da es leider verschiedene Probleme geben kann erläutere ich nun hier nochmal im Detail wie man die beiden Möglichkeiten einbringt.

PDF-Printing mit Apache FOP

Hier wird mit der XSL-FO Engine <a href="http://xmlgraphics.apache.org/fop/">FOP</a> von Apache gearbeitet, die das PDF dann erzeugt. Um diese zu benutzen kann man einerseits das in APEX 3.0.1 enthaltene Paket benutzen oder man lädt sich das ganze direkt hier runter: http://www.apache.org/dyn/closer.cgi/xmlgraphics/fop.
Da die unterschiedlichen Möglichkeiten in verschiedenen Systemen benötigt werden hier Tips dazu.

Tips zum original Oracle Howto

Zuerst lädt man sich den Standalone OC4J-Container runter. http://www.oracle.com/technology/software/products/ias/htdocs/utilsoft.html
Wichtig ist nach dem entpacken, dass man zuerst die Angaben für ORACLE_HOME und JAVA_HOME in der /oc4j/bin/oc4j (oc4j.cmd unter Windows) richtig setzt.
Einstellung unter Linux:

ORACLE_HOME=/oc4j
JAVA_HOME=/usr/lib/java

Einstellung unter Windows:

ORACLE_HOME=D:\programme\oc4j
JAVA_HOME=D:\Programme\Java\jdk1.6.0

Man sollte auch darauf achten das man ein JDK (JDK -> Entwicklung) und kein JRE (JRE -> nur Laufzeitumgebung) verwendet.

Danach sollte man wie beschrieben APEX aufrufen und dort den internal Workspace. Bei Printing Eigenschaften dann diese Einträge verwenden:

Oracle BI Publisher: Standard Support
Print Server Protocol: HTTP
Print Server Host Address: entsprechend die setzen des servers (meist localhost wenns auf dem gleichen System ist)
Print Server Port: 8888 (8888 sollte standard sein)
Print Server Script: /fop/apex_fop.jsp

Jetzt kann man einfach mal testweise bei der Workspaceübersicht auf drucken klicken und sollte ein PDF bekommen falls man dies als Standard definiert hat.

Tips zum deployen von FOP im Oracle Application Server

Falls das Systen schon einen Application Server besitzt ist es auch möglich Apache FOP dort zu installieren. Dabei ist es nötig, dass der Enterprise Manager des Middle-Tier hochgefahren werden muss. Dies kann man machen indem man sich als User welcher den Application Server hochfährt einloggt und danach das Environment des Middle-Tiers lädt (ORACLE_HOME=/.). Nun kann man mit

emrctl start iasconsole

den Enterprise Manager starten. Jetzt im Browser diesen aufrufen aufrufen mit

http://localhost:18101/emd

user: ias_admin
passwort: passwort

Falls das Passwort nicht mehr vorliegt, am besten im Middle-Tier bei den Logs der Installation mal reingucken.

Nachdem man die Adresse aufgerufen hat wählt man entweder eine OC4J Instanz aus oder erstellt eine neue. Meistens ist es ratsam eine neue zu erstellen, falls die anderen Container evtl. mal entfernt werden oder ähnliches, wenn ein Programm deinstalliert wird.
Dort klickt man nun auf WAR-Datei bereitstellen und nimmt die fop.war aus dem APEX 3.01 Installationsverzeichnis. Folgende Einstellungen sollten dabei gesetzt werden:

Web Anwendung= <auswählen der fop.war>
Anwendungsname= fop
URL zuordnen= /fop

... mit BI Publisher

Diese Möglichkeit wird auch soweit auf der APEX Seite beschrieben. http://www.oracle.com/technology/products/database/application_express/html/configure_printing.html

Drucken mit Browser

  • IE 7 - zu klein gedruckt -> Meistens daher, dass der Drucker die Seitengrößer anpasst, was unter Drucken -> Einstellungen -> Effekte anpassbar ist. Dort sollte entweder 100% stehen oder drucken auf A4.

Arbeiten mit APEX

APEX Mail / apex_mail

Freischaltung der Network ACL

Hinzufügen der ACL

begin
 dbms_network_acl_admin.create_acl(acl         => 'mailserver_acl.xml',
                                   description => 'Accessing the Mailingsystem',
                                   principal   => 'APEX_040000',
                                   is_grant    => true,
                                   privilege   => 'connect');

 dbms_network_acl_admin.assign_acl(acl        => 'mailserver_acl.xml',
                                   host       => 'your_smtp_server_ip',
                                   lower_port => 25,
                                   upper_port => 25);
end;

Entfernen der ACL

begin
 dbms_network_acl_admin.unassign_acl(acl        => 'mailserver_acl.xml'
                                    ,host       => 'your_smtp_server_ip'
                                    ,lower_port => 25
                                    ,upper_port => 25);
 dbms_network_acl_admin.delete_privilege(acl       => 'mailserver_acl.xml'
                                        ,principal => 'APEX_040000'
                                        ,is_grant  => true
                                        ,privilege => 'connect');
 dbms_network_acl_admin.drop_acl(acl => 'mailserver_acl.xml'); 
end;

Abfragen:

select acl , principal , privilege , is_grant from DBA_NETWORK_ACL_PRIVILEGES;
select acl , host , lower_port , upper_port from DBA_NETWORK_ACLS;

Interactive Reports

Checkbox im Interaktiven Report

In der Abfrage sollte sowas stehen wie:

apex_item.checkbox(50, atf_id) "CHK"

Als Überschrift, damit man alle selektieren und abwählen kann sollte sowas stehen:

<input type="checkbox" onclick="$f_CheckFirstColumn(this)" />

Breite bei interaktiven Reports / interactive reports

<script type="text/JavaScript">
 $x('apexir_ATE_DESC').style.width = "200px";   
</script>

Bilder in Reports / Interactive Reports

select 
 spalte
,case when nvl(dbms_lob.getlength(picture),0) = 0
   then null
   else '<a href="' || apex_util.get_blob_file_src('P1001_BLOB_ITEM', id) || '">Image</a>' end picture
from table

Tabular Forms

  • Spalte ID_DISPLAY muss auf SHOW stehen und muss auch zur Spalte ID_DISPLAY verküpft sein, obwohl die Tabelle diese Spalte nicht hat.
  • Es kann ein Fehler mit dem Parsen eines Queries auftreten, falls man die Spalte mit der primären Sortierung löscht.

APEX Repository/Views

Abfragen aller Objekte und deren Autorisierungsschemata

 select 
  aaa.authorization_scheme_name 
, scheme.application_id
, scheme.page_id
, scheme.object_type
, scheme.object_name
from apex_application_authorization aaa
full outer join
(
select a.application_id, a.page_id, 'PAGE' object_type, a.page_name object_name, a.authorization_scheme from apex_application_pages a
union
select a.application_id, a.page_id, 'BRANCH' object_type, a.BRANCH_ACTION object_name, a.authorization_scheme from apex_application_page_branches a
union
select a.application_id, a.page_id, 'BUTTON' object_type, a.BUTTON_NAME object_name, a.authorization_scheme from apex_application_page_buttons a
union
select a.application_id, a.page_id, 'COMPUTATION' object_type, a.COMPUTATION object_name, a.authorization_scheme from apex_application_page_comp a
union
select a.application_id, a.page_id, 'ITEM' object_type, a.item_name object_name, a.authorization_scheme from apex_application_page_items a
union
select a.application_id, null page_id, 'LIST_ENTRIES' object_type, a.entry_text object_name, a.authorization_scheme from apex_application_list_entries a
union
select a.application_id, null page_id, 'NAV_BAR' object_type, a.ICON_SUBTEXT object_name, a.authorization_scheme from apex_application_nav_bar a
union
select a.application_id, a.page_id, 'PROCESS' object_type, a.process_name object_name, a.authorization_scheme from apex_application_page_proc a
union
select a.application_id, a.page_id, 'REGION' object_type, a.region_name object_name, a.authorization_scheme from apex_application_page_regions a
union 
select a.application_id, a.page_id, 'REPORT_COLS' object_type, a.COLUMN_ALIAS object_name, a.authorization_scheme from apex_application_page_rpt_cols a
union
select a.application_id, null page_id, 'TAB' object_type, a.tab_label object_name, a.authorization_scheme from apex_application_tabs a
union
select a.application_id, a.page_id, 'VALIDATION' object_type, a.VALIDATION_NAME object_name, a.authorization_scheme from apex_application_page_val a
union
select a.application_id, null page_id, 'APP PROCESS' object_type, a.process_name object_name, a.authorization_scheme from apex_application_processes a
) scheme on scheme.authorization_scheme = aaa.authorization_scheme_name and scheme.application_id = aaa.application_id
where aaa.authorization_scheme_name is not null or scheme.authorization_scheme is not null
order by aaa.authorization_scheme_name, scheme.page_id, scheme.object_name nulls last

Abfragen aller Objekte und deren Validierungen/Conditions

 select * from (
select pages.application_id, pages.page_id, 'PAGE' object_type, pages.page_name object_name, null condition_type, null condition_expression1, null condition_expression2 from apex_application_pages pages
union
select pregions.application_id, pregions.page_id, 'REGION' object_type, pregions.region_name object_name, pregions.condition_type, pregions.condition_expression1, pregions.condition_expression2 from apex_application_page_regions pregions
union 
select prptcols.application_id, prptcols.page_id, 'REPORT_COLS' object_type, prptcols.COLUMN_ALIAS object_name, prptcols.condition_type, prptcols.condition_expression1, prptcols.condition_expression2 from apex_application_page_rpt_cols prptcols
union
select pbuttons.application_id, pbuttons.page_id, 'BUTTON' object_type, pbuttons.BUTTON_NAME object_name, pbuttons.condition_type, pbuttons.condition_expression1, pbuttons.condition_expression1 from apex_application_page_buttons pbuttons 
union
select pitems.application_id, pitems.page_id, 'ITEM' object_type, pitems.item_name object_name, pitems.condition_type, pitems.condition_expression1, pitems.condition_expression2 from apex_application_page_items pitems
union
select pcomp.application_id, pcomp.page_id, 'COMPUTATION' object_type, pcomp.COMPUTATION object_name, pcomp.condition_type, pcomp.condition_expression1, pcomp.condition_expression2 from apex_application_page_comp pcomp
union
select pval.application_id, pval.page_id, 'VALIDATION' object_type, pval.VALIDATION_NAME object_name, pval.condition_type, pval.condition_expression1, pval.condition_expression2 from apex_application_page_val pval
union
select pproc.application_id, pproc.page_id, 'PROCESS' object_type, pproc.process_name object_name, pproc.condition_type, pproc.condition_expression1, pproc.condition_expression2 from apex_application_page_proc pproc
union
select pbranches.application_id, pbranches.page_id, 'BRANCH' object_type, pbranches.BRANCH_ACTION object_name, pbranches.condition_type, pbranches.condition_expression1, pbranches.condition_expression2 from apex_application_page_branches pbranches
union
select aale.application_id, null page_id, 'LIST_ENTRIES' object_type, aale.entry_text object_name, aale.condition_type, aale.condition_expression1, aale.condition_expression2 from apex_application_list_entries aale
union
select aanb.application_id, null page_id, 'NAV_BAR' object_type, aanb.ICON_SUBTEXT object_name, aanb.condition_type, aanb.condition_expression1, aanb.condition_expression2 from apex_application_nav_bar aanb
union
select aat.application_id, null page_id, 'TAB' object_type, aat.tab_label object_name, aat.condition_type, aat.condition_expression1, aat.condition_expression2 from apex_application_tabs aat
) cond 
order by cond.condition_type

Änderungen an Objekten einer Seite abfragen

 select * from (
 select pages.application_id, pages.page_id, 'PAGE' object_type, pages.page_name object_name, pages.LAST_UPDATED_BY, pages.LAST_UPDATED_ON from   apex_application_pages pages
 union
 select pregions.application_id, pregions.page_id, 'REGION' object_type, pregions.region_name object_name, pregions.LAST_UPDATED_BY,  pregions.LAST_UPDATED_ON from apex_application_page_regions pregions
 union 
 select prptcols.application_id, prptcols.page_id, 'REPORT_COLS' object_type, prptcols.COLUMN_ALIAS object_name, prptcols.LAST_UPDATED_BY,  prptcols.LAST_UPDATED_ON from apex_application_page_rpt_cols prptcols
 union
 select pbuttons.application_id, pbuttons.page_id, 'BUTTON' object_type, pbuttons.BUTTON_NAME object_name, pbuttons.LAST_UPDATED_BY, pbuttons.LAST_UPDATED_ON from apex_application_page_buttons pbuttons 
 union
 select pitems.application_id, pitems.page_id, 'ITEM' object_type, pitems.item_name object_name, pitems.LAST_UPDATED_BY, pitems.LAST_UPDATED_ON from apex_application_page_items pitems
 union
 select pcomp.application_id, pcomp.page_id, 'COMPUTATION' object_type, pcomp.COMPUTATION object_name, pcomp.LAST_UPDATED_BY, pcomp.LAST_UPDATED_ON from apex_application_page_comp pcomp
 union
 select pval.application_id, pval.page_id, 'VALIDATION' object_type, pval.VALIDATION_NAME object_name, pval.LAST_UPDATED_BY, pval.LAST_UPDATED_ON from apex_application_page_val pval
 union
 select pproc.application_id, pproc.page_id, 'PROCESS' object_type, pproc.process_name object_name, pproc.LAST_UPDATED_BY, pproc.LAST_UPDATED_ON from apex_application_page_proc pproc
 union
 select pbranches.application_id, pbranches.page_id, 'BRANCH' object_type, pbranches.BRANCH_ACTION object_name, pbranches.LAST_UPDATED_BY, pbranches.LAST_UPDATED_ON from apex_application_page_branches pbranches
 union
 select aale.application_id, null page_id, 'LIST_ENTRIES' object_type, aale.entry_text object_name, aale.LAST_UPDATED_BY, aale.LAST_UPDATED_ON from apex_application_list_entries aale
 union
 select aanb.application_id, null page_id, 'NAV_BAR' object_type, aanb.ICON_SUBTEXT object_name, aanb.LAST_UPDATED_BY, aanb.LAST_UPDATED_ON from apex_application_nav_bar aanb
 union
 select aat.application_id, null page_id, 'TAB' object_type, aat.tab_label object_name, aat.LAST_UPDATED_BY, aat.LAST_UPDATED_ON from apex_application_tabs aat
 ) aenderungen 
 order by aenderungen.last_updated_on desc nulls last

Entwickler Modus / Developer mode

IF APEX_Application.g_edit_cookie_session_id IS NOT NULL
THEN
... in developer mode ...
ELSE
... not in developer mode ...
END IF;

XLIFF - Übersetzung / Translation

Dynamic SQL with execute immmediate / Dynamisches SQL mit execute immediate

Quelle: http://ediyanto83.wordpress.com/2007/04/14/tuning-dynamic-sql-with-execute-immediate-and-cursor-variables/ DECLARE
TYPE EmpCurTyp IS REF CURSOR;
emp_cv EmpCurTyp;
v_name employees.last_name%TYPE;
v_sal employees.salary%TYPE;
my_sal NUMBER := 2000;
table_name VARCHAR2(30) := ‘employees’;
BEGIN
OPEN emp_cv FOR ‘SELECT last_name, salary FROM ‘ || table_name ||
‘ WHERE salary > ‘ || my_sal;
LOOP
FETCH emp_cv into v_name, v_sal;
EXIT WHEN emp_cv%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_name || ‘ ‘ || v_sal);
END LOOP;
CLOSE emp_cv;
END;

Löschbestätigung / Delete Confirmation

Folgende Sachen müssen benutzt werden um eine Bestätigung des Löschvorgangs abzufragen:

  • Der Button muss als Ziel eine URL haben und diese muss heißen:
    javascript:confirmDelete(htmldb_delete_message,'DELETE');
  • Im Header der Seite muss ein Javascript vorhanden sein was ca. so aussieht:
    <script language="JavaScript" type="text/javascript"> <!-- htmldb_delete_message='"DELETE_CONFIRM_MSG"'; //--> </script>
  • Schlussendlich muss man noch einen Prozess erstellen, welcher bei Bedingung den Request "DELETE" (in diesem Beispiel) benutzt um eine Aktion durchzuführen.

Suche in Reports

:P1201_SUCHE is null
or instr(upper(vom), upper(:P1201_SUCHE)) > 0

XML DB

http://www.oracle.com/global/de/community/tipps/xmldb-filesystem-2/index.html
http://www.cs.bris.ac.uk/maintain/oracle9docs/appdev.920/a96620/xdb20rpl.htm

 DECLARE
  l_int PLS_INTEGER;
 BEGIN
   l_int := dbms_xdb.changePrivileges(res_path => '/rss', ace => XMLTYPE('<ace
     xmlns="http://xmlns.oracle.com/xdb/acl.xsd" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd  
                         http://xmlns.oracle.com/xdb/acl.xsd 
                         DAV:http://xmlns.oracle.com/xdb/dav.xsd"> 
   <principal>RSS_DOAG</principal>
   <grant>true</grant>
   <privilege>
     <all/>
   </privilege>
</ace>'));
END;

Eigenes Authentifizierungsschema über Datenbanktabelle

  • Anwendung -> Gemeinsame Komponenten -> Authentifizierungsschemas -> Erstellen -> Völlig neu
  • Session nicht gültig Seite auf 101 setzen (meist die automatisch erstellte Anmeldeseite)
  • bei Anmeldeverarbeitung -> Authentifizierungsfunktion -> Funktion mit Parametern p_username und p_password und boolean als Rückgabewert dort angeben (return auth_pkg.login;)
  • Abmelde URL -> wwv_flow_custom_auth_std.logout?p_this_flow=&APP_ID.&p_next_flow_page_sess=4155:PUBLIC_PAGE

Problem der belegten Applikations ID

Falls man die Anwendung anfangs mal mit einer zufällig zugewiesenen ID erstellt hat, bekommt man nach der Löschung dieser Anwendung nicht die gleiche ID wieder zur Installation einer anderen oder der gleichen Anwendung. Dies ist ein Bug in 3.1.x. Weitere Infos dazu hier http://forums.oracle.com/forums/message.jspa?messageID=2812841#2812841
Als Workaround kann man entweder in einer Tabelle einen Eintrag entfernen
delete from flows_030100.wwv_flows_reserved where id = [enter id];
oder man erstellt die Anwendung nicht mit zufälliger sondern eigens ausgewählter ID.

Umwandeln von HTML Entities

wwv_flow_utilities.esc_non_basic_tags

Änderungen in Textfeldern markieren

Will man ein Originalwert und einen geänderten Eintrag auf einer Seite markieren, ist dies meistens mit einer farblich Markierung gut zu machen. Oft hat man dabei 2 Textfelder zum Eintragen (P1_TEXT und P1_A_TEXT). Dafür erstellt man nun für jedes Änderungsfeld ein weiteres Feld in der Art P1_G_TEXT. In diesem wird die unterschiedliche Formatierung als CSS Stylesheet definiert. Also für eine andere Farbe zum Beispiel style="color:red;". Folgende Schritte muss man dann insgesamt durchführen:

  • Elemtente erstellen P1_TEXT, P1_A_TEXT, P1_G_TEXT
  • Prozess erstellen der Nach Header (AFTER HEADER) läuft und einen Vergleich von P1_TEXT und P1_A_TEXT macht. Dabei wird P1_G_TEXT mit style="color:red;" gesetzt, wenn die Werte unterschiedlich sind (NULL aufpassen).
  • Nun setzt man bei dem Element P1_A_TEXT -> HTML-Form-Elementattribute = &P1_A_TEXT.

Select List / Auswahlliste Problem beim Übertragen von %null%

Lösung von Patrick Wolf aus dem Oracle Forum (http://forums.oracle.com/forums/message.jspa?messageID=2765402#2765402):

  • Create a Application Process (Shared Components\Application Process)
  • Name: RemoveNulls
  • Sequence: 0 (should be a number before any of your page level processes)
  • On submit: After Page Submission - Before Computations and Validations
  • Process Text

 BEGIN
   FOR rItem IN
     ( SELECT ITEM_NAME
         FROM APEX_APPLICATION_PAGE_ITEMS
        WHERE APPLICATION_ID   = TO_NUMBER(:APP_ID)
          AND PAGE_ID          IN (TO_NUMBER(:APP_PAGE_ID), 0)
          AND LOV_DISPLAY_NULL = 'Yes'
          AND LOV_DEFINITION   IS NOT NULL
          AND LOV_NULL_VALUE   IS NULL
     )
   LOOP
       IF V(rItem.ITEM_NAME) = '%null' || '%'
       THEN
           Apex_Util.set_session_state(rItem.ITEM_NAME, NULL);
       END IF;
   END LOOP;
 END;

Gleichzeitige Bearbeitung eines Datensatzes als Validierung

Diese Abfrage in einem Item speichern:
SELECT APEX_ITEM.MD5_HIDDEN(ID, UPDATED_USER, UPDATED_DATE, INSERTED_USER, INSERTED_DATE, ...) FROM TEST WHERE id = :P14_TEST_ID
Danach in der Validierung die gleiche Abfrage in einer lokalen Variable speichern und dann beide Werte vergleichen. Sind diese gleiche gibt die Validierung (RETURN BOOLEAN) true zurück und falls diese sich unterscheiden false. Dabei darauf achten, dass das Item zwingend bei jedem Seitenaufruf neu gesetzt wird und ggf. nur dann gesetzt wird, falls wirklich eine Bearbeitung stattfindet (kein Neueintrag).

Breite von Bereichen erzwingen

Einfach in den Header folgendes eingeben:
< div style="width:900px;">
und in den footer:
< /div>

Validations

Falls dort ausgewählt wurde: "Function Returning Boolean", wird beim Rückgabewert "false" die Fehlermeldung angezeigt und bei "true" ist alles in Ordnung.

Substitution Strings

APP_ALIAS
APP_ID
APP_IMAGES
APP_PAGE_ID
APP_SESSION
APP_UNIQUE_PAGE_ID
APP_USER
AUTHENTICATED_URL_PREFIX
BROWSER_LANGUAGE
CURRENT_PARENT_TAB_TEXT
DEBUG
HOME_LINK
LOGIN_URL
IMAGE_PREFIX
OWNER
PRINTER_FRIENDLY
LOGOUT_URL
PROXY_SERVER
PUBLIC_URL_PREFIX
REQUEST
SQLERRM

Anwendungslink / URL Syntax

OWA_UTIL.GET_CGI_ENV

Alle Einträge mittels

 FOR i IN 1..owa.num_cgi_vars LOOP
   insert into test (wert) values (owa.cgi_var_name(i)||' : '||owa.cgi_var_val(i));
 END LOOP;

http://' || owa_util.get_cgi_env ('HTTP_HOST') || owa_util.get_owa_service_path || 'f?p=' || :APP_ID

Weitere praktische Variablen

  • ora_rowscn
  • rowid

Beispiel

 http:// owa_util.get_cgi_env (HTTP_HOST) owa_util.get_owa_service_path f?p=APP_ID:APP_PAGE_ID:APP_SESSION:DEBUG::P9325_ID,P9325_TEXT:P9325_ID,:P9325_TEXT
 htp.p(lower(owa_util.get_cgi_env(q'#REQUEST_PROTOCOL#')) || 
             owa_util.get_cgi_env(q'#HTTP_HOST#') || 
             owa_util.get_owa_service_path || 
     'f?p=' || :APP_ID || 
     ':' || :APP_PAGE_ID || 
     ':' || :APP_SESSION || 
     '::' || :DEBUG || 
     '::' || 'P9325_ID,P9325_TEXT' ||
     ':' || :P9325_ID || ',' || :P9325_TEXT);

http://www.host.com:7777/pls/htmldb/f?p=180:53:7191864538699927::NO::P53_ID,P53_ID_NEWSTICKER_DC:144,22

APEX Community Tips

Ungefähr jeden Monat erscheint ein APEX Community Tip unter http://www.oracle.com/global/de/community/index.html . Dort kann man meistens recht interessante kleine Howtos lesen, welche auf Deutsch geschrieben wurden und ganz bestimmte Mechaniken abdecken.

Pie Charts

Problem der Überlappung von Beschriftungen bei einem Kuchendiagramm lösen http://igor-db.blogspot.com/2008/07/small-slices-of-pie.html

Checkbox allgemein

Bei einer Checkbox immer darauf achten, dass bei einem Report Checkboxen, die nicht angehackt sind (also nicht ausgewählt) auch nicht übertragen werden. Wer also ein Array von Werten überträgt, bekommt nur so viele Zeilen in dem Array der Checkbox wie angehackt wurden. Werden weitere Eigenschaften des Reports übertragen, so muss man sich künstlich behelfen um die Werte einer Zeile in Relation zueinander zu übertragen. Der Trick darin besteht in der Art, dass man in den Wert des Checkbox Feldes die ID des Eintrages gibt. Ist jetzt eine Checkbox angehackt, muss man bei Übertragung den Wert als Vergleich nehmen, welche Zeile / Datenbankzeile man aktualisiert. Der Wert der dann in das Feld kommt, muss dort noch angegeben werden. In der Abfrage des Reports sieht das ganze dann so aus:

 ,apex_item.checkbox(1, id, decode(spalte_ausgewaehlt, 1, ' checked ', )) auswahl

Beim Speichern wird dann das ganze so gemacht:

 for i in 1 .. apex_application.g_f01.count
 loop 
   update tabelle a set spalte_ausgewaehlt = 1
   where id = apex_application.g_f01(i);
 end loop;

Wenn man, wie oben kurz erwähnt, weitere Werte zu dieser Zeile mitspeichert und das mittels einem Update machen will/muss, so benötigt man ein "Hidden"-Feld, in welchem auch die ID liegt und falls in dem "Checkbox"-Array kein Wert mit dieser ID vorhanden ist, so ist für diese Zeile das Feld nicht ausgewählt.

Checkbox Select all

 function get_Checkboxes(p_itemname) {
  var ip=document.getElementsByTagName('INPUT');
  var ret=new Array();
  var regexp=new RegExp('^'+p_itemname+'_');
  for (var j=0;j<ip.length;j++) {
    if (ip[j].type=="checkbox" && ip[j].id && ip[j].id.match(regexp)) 
       ret.push(ip[j]);
  }
  return ret;
 }

und beim Element aufrufen

 <input type="checkbox" title="check all" onClick="html_CheckAll(null, this.checked, get_Checkboxes('P2_CHECK'))">

Quelle: http://forums.oracle.com/forums/thread.jspa?threadID=365836&start=0&tstart=0

Array in APEX

Bei Updateable Reports benötigt man Arraystrukturen die dann beim Bearbeiten / eintragen in die Datenbank durchlaufen werden müssen. Diese sind vom Typ wwv_flow_global.vc_arr2 / APEX_APPLICATION_GLOBAL.VC_ARR2. Der Name eines solchen Arrays ist "APEX_APPLICATION.G_F01" wobei die Nummer am Ende jeweils die Spalte angibt.
Mittels diesem Aufruf kann man sie durchlaufen:

 for i in 1 .. apex_application.g_f01.count
 loop 
   htp.p('element '||I||' has a value of '||APEX_APPLICATION.G_F01(i)); 
 end loop;

Mittels diesem Aufruf kann man die Werte in einen String umwandeln:

 APEX_UTIL.TABLE_TO_STRING(APEX_APPLICATION.G_F01)

Diese sind dann in der Form "2:3:4". Die Funktion geht auch zurück und heist dann STRING_TO_TABLE. Umwandlung zum TAble nach dieser Art http://stackoverflow.com/questions/429508/are-there-alternative-methods-for-saying-next-in-a-pl-sql-for-loop

Cookie setzen

Dies als Prozess schreiben:

 begin
 owa_util.mime_header('text/html', FALSE);
 owa_cookie.send(
     name=>'LOGIN_USERNAME_COOKIE',
     value=>lower(:P101_USERNAME));
 exception when others then null;
 end;

AJAX in APEX

Hier ne kleiner Beschreibung zur Benutzung von AJAX in APEX

Zuerst nen Item erstellen, in welchem man ein Javascript aufruft. Für einen Button zum Beispiel:

 onclick="getFileContent('P1_VAR1','P1_VAR2')";

Nun muss diese Methode als Javascript existieren. In APEX kannst entweder nen Javascript als *.js erstellen und hochladen oder im Header der Page/Region nen Javascript direkt reinschreiben (so lang man entwickelt besser in Pageheader oder Regionheader reinschreiben, da man so viel schneller noch Veränderungen machen kann). Könnte zum Beispiel so aussehen:

function getFileContent(filename, item_textarea, item_dateiname) {
 document.getElementById(item_dateiname).value = filename;
 document.getElementById('P1_SPEICHERN').disabled = false;

 var ajaxRequest = new htmldb_Get(null, &APP_ID., 'APPLICATION_PROCESS=READ_FILE_CONTENT_FROM_PORTAL', 0);
 ajaxRequest.add(item_dateiname, filename);
 ajaxResult = ajaxRequest.get();
 var textareaObj = document.getElementById(item_textarea);
 textareaObj.value = ajaxResult;
}

Wie man sehen kann kommt man entweder mittels document.getElementId('Itemname').value an den Namen oder man überträgt die Namen als Variablen und setzt diese bei getElementId ein. Der Ajaxaufruf ist hier mittels "new htmldb_Get" erzeugt worden und ruft nen On Demand Prozess auf (siehe nächster Absatz). Der Aufruf wird über ajaxRequest.get(); gemacht wobei vorher entsprechend Variablen noch hinzugefügt werden können.

In der Variable ajaxResult ist das Ergebnis des Prozesses drin und die letzte Zeile im Javascript schreibt das Ergebnis auf eine textarea bei mir.

Der On Demand Prozess wird über SHARED COMPONENTS -> APPLICATION EXPRESS erstellt. In den Prozessaufruf kannste nun beliebige PL/SQL Aufrufe reinbauen, welche über htp.prn(Aufruf) gemacht werden müssen da dieses htp.prn nen Rückgabewert liefert, den der AJAX Prozess als Ergebnis hat. Das könnte so aussehen:

 htp.prn(read_file_content_from_portal(:P1_DATEINAME));

Hier wird also ne Prozedur aufgerufen die den Inhalt einer Datei aus dem Portal abfragt. Der Wert wird dann ins Javascript zurückgegeben.

Weiterleiten mit Return

onkeypress="return submitEnter(this,event)"

Beispiele

Fileupdload/Download

 PROCEDURE pr_save_datei(
       p_dateiname     VARCHAR2
   )
   IS
       v_mime_type VARCHAR2(100);
       v_inhalt    BLOB;
       v_dateiart  VARCHAR2(3);
       v_dateiname VARCHAR2(50);
   BEGIN
       v_dateiart := substr(p_dateiname, instr(p_dateiname, '.', -1, 1)+1,3);
   
       SELECT blob_content, mime_type, filename
       INTO v_inhalt, v_mime_type, v_dateiname 
       FROM wwv_flow_files WHERE name = p_dateiname;
       
       INSERT INTO dokument 
               ( dateiname
               , inhalt
               , mime_type
               , dateiart
               )
       VALUES  ( v_dateiname 
               , v_inhalt
               , v_mime_type
               , v_dateiart
              );
     DELETE FROM wwv_flow_files WHERE name = p_dateiname;
 END pr_save_datei;

Oracle Tip für Fileupload
Oracle Tip für Filedownload

select
 id,
 dateiname,
 mimetype,
 letzte_aenderung,
 dbms_lob.getlength(dateiinhalt) as download_link,
 apex_util.filesize_mask(dbms_lob.getlength(dateiinhalt)) as datei_groesse
from tab_dateien

DOWNLOAD:TAB_DATEIEN:DATEIINHALT:ID::MIMETYPE:DATEINAME:LETZTE_AENDERUNG::attachment:Herunterladen

Anychart Integration

http://www.youtube.com/watch?v=S7-hACPj7t8&feature=player_embedded

Plugins

Links zum Thema APEX Plugins:

Tools & weiteres

  • Plsql als Programmiersprache
  • plsqldeveloper oder sqldeveloper als Entwicklungstools
  • Apex Builder Plugin als Browserscript für Grease Monkey
  • Firefox inkl. Firebug, GreaseMonkey, LiveHeaders, NoScript, Colorzilla

Javascript in APEX

  • Weiterleiten auf beliebigen Elementen mittels doSubmit('REQUEST')
  • Weiterleiten mit Enter und Name des Objekts als Request onkeypress="return submitEnter(this,event)"
  • Weiterleiten mit Enter und eigenem Request

onkeypress="submitEnterRequest(event,'LOGIN')" 

und als Javascript im Seitenheader hinterlegt

<script language="javascript" type="text/javascript">
function submitEnterRequest(e,request){
 if (e.keyCode == 13) { 
  doSubmit(request);
 }
}
</script>

APEX Packages und Funktionen

  • Umwandlung von Blob zu Clob und andersrum ist in APEX als Utility enthalten. Dabei kann man sogar noch das Zielcharset angeben falls die Datenbank ein anderes besitzt als die Zieldatei:

 v_blob := wwv_flow_utilities.clob_to_blob( p_clob => v_clob
                                          , p_charset => general.NLS_CHARACTERSET_FILE
                                          );

  • Export von einzelnen Seiten oder der ganzen Anwendung als clob über APEX Packages. Auch diese Funktionen/Prozedur befinden sich im wwv_flow_utilities Package.

procedure export_application_to_db (p_application_id   in number);
function export_application_to_clob (p_application_id   in number, p_export_saved_reports in varchar2 default 'N') return clob;
function export_page_to_clob (p_application_id   in number, p_page_id in number) return CLOB;

Nice to have APEX / Bugs bis 3.2.1

  • Import Application -> freie Application IDs anzeigen
  • NULL Wert übertragen bei Listen (Problem %NULL% wird übertragen)
  • 100 Item Beschränkung
  • 50 Array Beschränkung
  • datepicker wert nicht in kalenderdarstellung übernommen
  • Problematik Checkbox <-> Zuordnung zu Zeile schwierig und nicht über Standard enthalten.

Checkbox/Radiobutton nicht immer aktuell

Bei Aktualisierung eines SQL Reports wo der Datensatz der ausgewählt wurde nicht mehr vorhanden ist wird dieser trotzdem übermittelt. Als Workaround muss momentan eine Funktion erstellt werden, welche die Abfrage der aktuellen Daten nochmals durchführt und dann ggf. die Ergebnisse filtert.

Tips aus dem Buch Pro Oracle Application Express

Workspaces & Deployment

  • wenn ein Entwickler erstellt wird, dass Schema leer lassen so hat er Zugriff auf mehrere Schemata beim Erstellen der Anwendung.
  • Export vom Workspace ermöglicht die Mitnahme der Anwender, falls diese als APEX Benutzer erstellt wurden. Außerdem werden alle Daten wie Grafiken und CSS automatisch mitgenommen.
  • statische Dateien wie Grafiken und CSS abwägen, ob sie auf dem Apache Verzeichnis oder in der Datenbank laden sollen.
    • Im Apache Verzeichnis: Caching vorhanden aber für Änderungen sind Rechte auf dem Server nötig um die Bilder hochzuladen. Außerdem ist die Verwaltung und das Updaten komplizierter
    • In der Datenbank ist standardmäßig kein Caching vorhanden. Bei jedem Laden wird ein Bild neu generiert. Traffic und Belastung der Datenbank beachten.
  • Substition Strings benutzen (APP_ID, APP_SESSION, APP_PAGE_ID, ...)
    • Page-Alias-Name kann in URL verwendet werden. (falls Seitennummer sich ändert) &APP_ID.:1:&APP_SESSION. = &APP_ID.:HOME:&APP_SESSION. (falls Page Alias auf Seite 1 = HOME)
    1. APP_IMAGES# verwenden (Adresse: #APP_IMAGES#logo.gif). Falls Möglichkeit offen gehalten wird wo die Images liegen sollen (Datenbank oder Filesystem/Apache), dann Substition IMAGE_PATH = #APP_IMAGES# einbauen und später ändern in IMAGE_PATH = /i/live_images

Entwicklung

  • LOVs für mehrere Anwendungen zentral in einer Hauptanwendung erstellen und in einzelnen Unteranwendungen abonieren.
  • LOV Abfragen ohne HTML Zeichen erstellen, da sonst die Datenbank inhaltlich gleiche Anfragen nicht über Cache abwickeln kann.
  • Seite 0 benutzen, für Elemente die mehrfach in der Anwendung auf verschiedenen Seiten gleich gebraucht werden.
  • Bei Reports besteht, bei Date Feldern auch die Möglichkeit Zeiträume anzugeben indem man das Format anpasst (Zum Beispiel vergangene Monate oder Stunden anzeigen statt dem Datum etc.)

Authentication & User Management

  • Open Door Credentials - jeglicher Username kann verwendet werden ohne diesen zu validieren. Schema eignet sich hervorragend für Tests.
  • No authentication - Jeder User ist als APEX_PUBLIC_USER/HTMLDB_PUBLIC_USER unterwegs (wird aus der dads.conf Einstellung abgeleitet).
  • Application Express account credentials - User muss über die APEX Benutzerverwaltung erstellt werden und kann sich dementsprechend einloggen. Gruppen können auch erstellt werden.
    • Funktion vorhanden um eine Validierung durchzuführen (falls nicht -BUILTIN- benutzt wird).
      Weitere Funktionen wie Abfrage der Gruppenzugehörigkeit oder anlegen von Benutzern etc sind auch vorhanden im Package apex_util.
apex_util.function is_login_password_valid(p_username in varchar2, p_password in varchar2) return boolean
  • Database account authentication - Datenbankbenutzer werden zur Überprüfung der Logindaten verwendet. Innerhalb der Anwendung taucht der Benutzer als APEX_PUBLIC_USER auf (dads.conf).
  • LDAP directory - Standard LDAP Verzeichnis benutzen
  • Application server single sign-on - Zum Beispiel SSO über einen Application Server
  • custom authentication theme - Schema mit eigener Benutzertabelle und Authentifikationsmethode.
    • Autentifizierungsmethode mit der Signatur (p_username in varchar2, p_password in varchar2) return boolean muss benutzt werden.
    • Groß/Kleinschreibung bei Validierung beachten. Bei sehr großen Benutzertabellen sollte man einen Index für upper anlegen.
create index benutzer_uppder_idx on benutzer(upper(username))
    • Salt beim Passwort verschlüsseln verwenden. Das ganze mit Hashfunktion verschlüsseln. Alles im Package dbms_obfuscation_toolkit enthalten.
    • Ggf. Einbau von Sperrungen für Benutzer, sowie Anpassung der Informationen und automatisierte Mails falls ein Benutzer sein Passwort neu erstellen lassen will.

Import & Export

  • CSV Export kann über einfache Anpassung dynamisch gemacht werden und die Trennzeichen und Struktur kann so angepasst werden. Custom Export to CSV
  • Import von Access über CSV Dateien oder ODBC Schnittstelle. Bei Nutzung von ODBC muss im Access ein DSN eingerichtet werden mit dem Oracle ODBC Treiber.
  • Als Tool kann auch Orcle Migration Workbench genutzt werden. (Imports von MySQL, Sybase, IBM Informix, Microsoft SQL, IBM DB2/400, DB2 UDB) Bei einer Access Anwendung kann innerhalb der Anwendung noch einer Datenbankmigration auch der Zugriff auf die Oracle Datenbank umgestellt werden.

Performance

  • Bind Variablen verwenden.
    • Höhere Sicherheit (keine Code Injection). Notation &P12_ID. unsicherer als :P12_ID
    • Bessere Performance als über Funktion :P12_ID kann sofort referenziert werden. v('P12_ID') muss über Funktion aufgelöst werden.
    • Bessere Lesbarkeit > :P12_ID ist kürzer und damit besser lesbar
  • Exceptionhandling in anonymen SQL Blöcken verwenden:
    • exception when no data found then :APP_ERROR_MSG := 'Hier kommt die individuelle Fehlermeldung.';
  • So viel in Packages auslagern wie möglich.
    • Bessere Übersicht bei Fehlern.
    • Bessere Wiederverwendbarkeit, sowohl auf anderen Seiten, als auch von anderen Anwendungen.
    • Einfacher Änderungen durchzuführen.
  • Debug Modus auf einer Seite benutzen um genau zu wissen, welche Bereiche wie lange benötigen.