APEX
Aus Xmaswiki
Verwendung der Programmiersprache plsql.
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
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.
- http://www.oracle.com/technology/tech/linux/install/xe-on-kubuntu.html
- http://www.ridikuel.de/blog/2007/01/08/neues-oracle-xe-tutorial-debian-von-benjamin-reiter/
- http://syslog.warten.de/2007/08/installation-von-oracle-databa.html
- http://www.debian-administration.org/articles/430
- http://wiki.openbravo.com/wiki/Install_oracle_debian/de
- http://wiki.openbravo.com/wiki/index.php/Build_svn_sources/de_de
- http://www.tgunkel.de/it/software/doc/sql_database.de
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
- Infos dazu unter: APEX Postinstallation Tasks http://download.oracle.com/docs/cd/B28359_01/install.111/b32002/post_inst_task.htm#BABEBICC
- http://oraexplorer.blogspot.com/2007/11/oracle-apex-in-11g-installation.html
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(true);
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)
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 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>@apxxepwd
SQL>conn sys/sys_passwort@xe as sysdba
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 rückganging machen
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:
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
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
- http://onlineappsdba.com/index.php/2008/09/17/oracle-application-express-apex-architecture-and-changes-from-oracle-database-11g/
- Konfiguration des Remote Access
- Installation auf Linux mit 11g XE Beta
- APEX 4.0 auf 10gR2
APEX Listener
- http://www.oracle.com/technetwork/developer-tools/apex-listener/overview/index.html
- Infos zu Listener Version 1.1
- Standalone Listener
- Listener auf Tomcat 6
- Freeware Umgebung mit Linux
- Glasfish Installation
- Glasfish Konfiguration
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
- 11g direkte Authentifizierung über die Datenbank oracle.com
- http://jastraub.blogspot.com/2008/03/ntlm-http-authentication-and.html Kommentare und Infos dazu auch im Oracle Forum weiterer Forenlink Oracle Forum
- Einstellungen für den Apachen
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
- Oracle XML Gateway funktioniert nicht damit.
- Angeblich soll das ganze durch das Sicherheitsupdate KB963027 mit dem IE7 nicht mehr gehen.
- Für IE8/WIN7 muss man gewisse Änderungen vornehmen oder mal diese Sache versuchen Quelle:
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"
- ansonsten auch das probieren http://www.thomasmaurer.ch/2009/07/problem-with-ntlm-authentication-with-ie8-on-windows-server-2008/
- http://withasmiletomeltathousandhearts.wordpress.com/2009/01/29/apex-windows-integrated-authentication/
- Um das Active Directory außerhalb von APEX / Datenbank abzugfragen eignet sich der AD Explorer.
- Falls man das ganze sicher über das Active Directory abwickeln will sollte man es über mod_ntlm versuchen http://withasmiletomeltathousandhearts.wordpress.com/2009/01/29/apex-windows-integrated-authentication/
- Weiterer Guide zur NTLM Authentifzierung http://bahzzkillington.blogspot.com/
- Code für Validierung des IE/ ggf. für eine Umleitung
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
- Allgemeine Infos zu Kerberos (wikipedia)
- Kerberos vs NTLM
- Kerberos mod für Apache
- Oracle Forum - Configuration Apache with Kerberos
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
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.add_privilege(acl => 'mailserver_acl.xml',
principal => 'APEX_040000',
is_grant => true,
privilege => 'resolve');
dbms_network_acl_admin.assign_acl(acl => 'mailserver_acl.xml',
host => 'your_smtp_server_ip',
lower_port => 25,
upper_port => 25);
end;
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
- http://server/pls/apexf?p=1000:1:
- 1000 = AnwendungsID oder auch :APP_ID oder auch Anwendungsalias (Edit Definitions)
- 1 = Seite, kann auch über Page Alias auf Basis der Seite direkt angesteuert werden.
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);
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.
- - Der Webserver von Application Express: PL/SQL Embedded Gateway oder Apache
- 18.07.2008 - Volltextrecherche erste Schritte
- 01.08.2008 - Volltextsuche Wartung und Pflege
- 25.08.2008 - SSO in mehreren APEX Anwendungen
- 27.11.2008 - Bilder manipulieren und bearbeiten
- 11.12.2008 - AJAX-Programmierung mit Application Express und der jQuery-Bibliothek
- 09.01.2009 - Betriebssystem-Kommandos und Dateisystemzugriffe mit Application Express (nicht XE)
- 09.01.2009 - DBMS_OUTPUT mit Application Express nutzen
- 06.02.2009 - Geodaten und Application Express: OpenStreetMap und OpenLayers
- 20.02.2009 - Berichte automatisch aktualisieren
- 05.03.2009 - Datumseingaben mit AJAX vereinfachen...
- 18.03.2009 - Data Mining mit der Oracle-Datenbank und Application Express
- 06.04.2009 - Firefox Such-Plugins für Application Express-Anwendungen
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:
- Infos allgemein zu verschiedenen Plugins von Patrick Wolf http://www.inside-oracle-apex.com/oracle-apex-4-0-how-to-create-a-plug-in/
- Dimitrie Gielis erklärt wie er sein editable Select List Plugin gemacht hat http://dgielis.blogspot.com/2010/01/apex-40-my-first-plugin-editable-select.html
- Feedreader Plugin http://www.lgcarrier.com/2010/01/apex-40-ea1-plugins-google-feed.html
- Slider Plugin http://blog.whitehorses.nl/2009/12/21/creating-plugin-item-types-using-apex-4-0/
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)
- 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.
- Funktion vorhanden um eine Validierung durchzuführen (falls nicht -BUILTIN- benutzt wird).
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.
