Anfang der Woche besuchte ich die Oracle Develop im Arabella Sheraton München. Sehr schönes Hotel, jedoch mussten wir zwischen den Vorträgen immer zwischen unterschiedlichen Gebäuden hin und herlaufen. Und die Kaffeemaschine war natürlich in dem Gebäude in dem nur 1 der 5 parallelen Slots stattfand
Tag 1:
Montag früh startete ich mit Frank Nimphius' Vortrag über Forms, die Zukunft von Forms und die Integration in Java, SOA, ...
Marc Sewtz und sein "SQL Developer Features" war nett, da wir eine Fülle neuer Feature des aktuellen Releases zu sehen bekamen
Nach dem Mittagessen gab es einen phantastischen Bryn Llewellyn mit "PL/SQL Performance: Debunking the Myths". Einfach klasse! Das nächste Mal kriegt er hoffentlich zwei Stunden und nicht nur eine.
Parallel zu den Vorträgen gab es 3 Labs von Oracle. Montag nachmittag schaute ich mir die neue APEX 3.0 Version an.
Tag 2:
Schlechte Nachrichten an der Kaffee-Front. Wir mussten weiterhin ein paar 100m im Freien mit unserem Kaffee von Hotel A nach Hotel B laufen, wenn wir dort was trinken wollten.
Dienstags schaute ich mir das nächste Lab an: "Developing and Deploying Oracle and PHP". Sehr interessant zu sehen, wie einfach PHP in Oracle integriert werden kann.
Danach präsentierte Bryn "PL/SQL-Enhancements of the new Oracle DB 11g". Ich liebe die Compound Triggers! Zusammen mit all den anderen neuen Techniken. Sequencen, die nun direkt angesprochen werden können und nicht mehr über DUAL !!
Nach dem Mittagessen präsentierte Frank Nimphius "Building Rich UI using JavaServer Faces and AJAX". Dies war ein weiteres Highlight Konferenz.
Interessant, wieviel Microsoft-Themen in den Vorträgen adressiert wurden. "Microsoft Interoperability with Oracle Fusion Middleware" zeigte die SOA-Integration, die mit dem Office-Toolstack ermöglicht wird. Schön zu sehen, wie andere Firmen das machen.
Zusammenfassung:
Vorträge und Labs: TOP
Kein Kaffee: FLOP
22. Juni 2007
10. Mai 2007
Neues Forms Look & Feel
Gute Nachrichten für alle Forms-Entwickler, die ihre Masken einmal in einem neuen Look and Feel sehen möchten.
In Grant's neuestem Interview sprach er mit Francois Degrelle, über sein Forms Look & Feel White Paper von April 2007.
In Grant's neuestem Interview sprach er mit Francois Degrelle, über sein Forms Look & Feel White Paper von April 2007.
17. April 2007
Schnellerer Forms-Start mit Synchronize
I konnte es gar nicht glauben, aber es klappt in manchen Fällen!
Wenn man in einer Forms-Anwendung den Eindruck hat, dass der Forms-Start zu langsam vonstatten geht, dann sollte man einen Synchronize einbauen um den Bildschirm beim Starten zu refreshen. Der Anwender denkt nun, dass die Maske schneller startet, intern wurde jedoch nur das Refreshen des Bildschirms vorgezogen.
probier es aus!
Wenn man in einer Forms-Anwendung den Eindruck hat, dass der Forms-Start zu langsam vonstatten geht, dann sollte man einen Synchronize einbauen um den Bildschirm beim Starten zu refreshen. Der Anwender denkt nun, dass die Maske schneller startet, intern wurde jedoch nur das Refreshen des Bildschirms vorgezogen.
WHEN-NEW-FORM-INSTANCE - trigger
BEGIN
synchronize;
-- your WHEN-NEW-FORM-INSTANCE-code
END;
probier es aus!
5. April 2007
EOUC 2007 wurde abgesagt
hmmmmmm...
die EMEA-Oracle-User-Council-Konferenz in Amsterdam wurde gerade abgesagt:
EOUC 2007
Update Dez. 2007: mittlerweile wurde sogar diese URL gecancelt
die EMEA-Oracle-User-Council-Konferenz in Amsterdam wurde gerade abgesagt:
EOUC 2007
Update Dez. 2007: mittlerweile wurde sogar diese URL gecancelt
4. April 2007
Multi-Select from DUAL
Ein einfacher Weg um Datensätze aus dem Nichts zu erzeugen ist ein einfacher SELECT mit einem CONNECT BY gegen DUAL.
Wenn man zum Beispiel in einer Forms-LOV die letzten 12 Monate anzeigen möchte, dann benötigt man eine Record-Group, die genau 12 Datensätze zurückgibt. Danach kombiniert man das noch mit dem Sysdate:
jetzt bringt man Sysdate ins Statement:
ist das nicht eine genial einfache Lösung für die Selektion der letzten 12 Monate?
Wenn man zum Beispiel in einer Forms-LOV die letzten 12 Monate anzeigen möchte, dann benötigt man eine Record-Group, die genau 12 Datensätze zurückgibt. Danach kombiniert man das noch mit dem Sysdate:
SELECT Level LVL
FROM Dual
CONNECT BY Level <= 12;
jetzt bringt man Sysdate ins Statement:
SELECT add_months (trunc (sysdate, 'MM'), -1*Level) Month
FROM Dual
CONNECT BY Level <= 12;
MONTH
--------
01.03.07
01.02.07
01.01.07
01.12.06
01.11.06
01.10.06
01.09.06
01.08.06
01.07.06
01.06.06
01.05.06
ist das nicht eine genial einfache Lösung für die Selektion der letzten 12 Monate?
14. März 2007
Assertions
Assertions im Sourcecode sind Alltag in Java und anderen Programmiersprachen. Warum also nicht auch bei uns in PL/SQL?
Das ist eine gute Frage und ich löste sie für meine Fragestellungen mit dieser Technik:
In diesem Beispiel schreibt man alle negativen Assertions untereinander und startet entsprechende Exceptions, die im Exception-Handling nichts tun.
z.B.
was wir hier sehen ist sehr einfach: Wenn man annimmt, dass nur Manager das doppelte Gehalt bekommen, dann kann man die Prozedur direkt nach dem Start abbrechen. Man springt in die e_Assertion-Exception und tut nichts.
Try it
Gerd
Das ist eine gute Frage und ich löste sie für meine Fragestellungen mit dieser Technik:
DECLARE e_Assertion EXCEPTION; BEGIN IF condition1 = 'value' OR boolean = TRUE OR something_else THEN RAISE e_Assertion; END IF; -- weiterer Code: ... EXCEPTION WHEN e_Assertion THEN NULL; WHEN OTHERS THEN -- when-others-exception-handling END;
In diesem Beispiel schreibt man alle negativen Assertions untereinander und startet entsprechende Exceptions, die im Exception-Handling nichts tun.
z.B.
PROCEDURE Double_Manager_Salary (P_EMPNO IN NUMBER, P_JOB IN VARCHAR2) IS e_Assertion EXCEPTION; BEGIN IF P_Job != 'MGR' THEN RAISE e_Assertion; END IF; UPDATE EMP SET SAL = SAL * 2 WHERE EMPNO = P_EMPNO; EXCEPTION WHEN e_Assertion THEN NULL; END;
was wir hier sehen ist sehr einfach: Wenn man annimmt, dass nur Manager das doppelte Gehalt bekommen, dann kann man die Prozedur direkt nach dem Start abbrechen. Man springt in die e_Assertion-Exception und tut nichts.
Try it
Gerd
12. Februar 2007
Einladung zur EOUC 2007
Die EMEA Oracle User Council Konferenz ist in diesem Jahr in Amsterdam vom 2.-3. Mai.
Mein Vortrag, den ich vor einigen Monaten eingesendet hatte lautet:
Oracle Forms 10g und die Integration in BPEL
Heute bekam ich die Einladung für den 3. Mai
Mein Vortrag, den ich vor einigen Monaten eingesendet hatte lautet:
Oracle Forms 10g und die Integration in BPEL
Heute bekam ich die Einladung für den 3. Mai
20. Januar 2007
One Time Timer
Sehr oft muss ich während der Validierung eine Navigation starten. Restricted Built-Ins kann man jedoch nicht benutzen. Wir brauchen einen Workaround:
Dies ist der "One Time Timer":
Beispiel: Ich habe einen Control-Block mit ein paar Feldern. Unter diesem Block ist ein Multi-Record Block namens EMP. Der Control-Block dient als Filter.
Der Anwender gibt Filterkriterien ein und automatisch wird nach jedem ausgefüllten Feld eine Query im darunterliegenden EMP Block gestartet. Das ist jedoch unmöglich, da Navigation im Validierungstrigger nicht erlaubt ist und in diesem Fall ein Go_Block und Execute_Query benötigt würden.
Lösung: Erstelle einen Form-Ebene WHEN-TIMER-EXPIRED-Trigger:
Erstelle eine Konstanten-Package mit einigen Konstanten:
und ein Package mit einigen Funktionen:
Der Control-Block (namens "Filter") hat z.B. zwei Items: ENAME und SAL
Erstelle einen WHEN-VALIDATE-ITEM auf ENAME:
letzter Schritt: der EMP-Block benötigt einen PRE-QUERY-Trigger auf Block-Ebene:
was passiert nun?
Nach dem Ändern eines Wertes in ENAME im FILTER-Block startet der WHEN-VALIDATE-ITEM auf diesem Feld. Er initialisiert den One-Time-Timer. Die globale Variable "global.One_Time_Timer" bekommt den Wert Const.ott_Query_in_EMP zugewiesen (= "Filter EMP-Block"). Danach startet der Timer und feuert nach 10 ms.
10ms später:
Der WHEN-TIMER-EXPIRED startet den execute_query im EMP-block und springt danach zurück auf das Feld, in dem der Cursor stand. Im EMP-block startet der PRE-QUERY und die Daten des EMP-Blocks werden gefiltert durch ":EMP.ENAME := :Filter.ENAME"
das war's schon. Viel Spass damit!
Dies ist der "One Time Timer":
Beispiel: Ich habe einen Control-Block mit ein paar Feldern. Unter diesem Block ist ein Multi-Record Block namens EMP. Der Control-Block dient als Filter.
Der Anwender gibt Filterkriterien ein und automatisch wird nach jedem ausgefüllten Feld eine Query im darunterliegenden EMP Block gestartet. Das ist jedoch unmöglich, da Navigation im Validierungstrigger nicht erlaubt ist und in diesem Fall ein Go_Block und Execute_Query benötigt würden.
Lösung: Erstelle einen Form-Ebene WHEN-TIMER-EXPIRED-Trigger:
DECLARE
V_Item VARCHAR2 (61);
BEGIN
V_Item := :SYSTEM.CURSOR_ITEM;
IF One_Time_Timer.Get_Value = Const.ott_Query_in_EMP THEN
Go_Block ('EMP');
Execute_Query;
Go_Item (V_Item);
ELSIF One_Time_Timer.Get_Value = Const.ott_Something_Else
THEN
-- if more One-Time-Timer are needed,
-- create one for each Branch
NULL;
END IF;
END;
Erstelle eine Konstanten-Package mit einigen Konstanten:
PACKAGE Const IS
-- Globals
gbl_One_Time_Timer CONSTANT VARCHAR2 (61) :=
upper ('global.One_Time_Timer');
-- One-Time-Timer
ott_Query_in_EMP CONSTANT VARCHAR2 (30) :=
'Filter EMP-Block';
ott_Something_Else CONSTANT VARCHAR2 (30) :=
'Something else';
END;
und ein Package mit einigen Funktionen:
PACKAGE One_Time_Timer IS
FUNCTION Get_Value RETURN VARCHAR2;
PROCEDURE Initialize (P_Event IN VARCHAR2);
END;
PACKAGE BODY One_Time_Timer IS
FUNCTION Get_Value RETURN VARCHAR2 IS
BEGIN
Default_Value (NULL, Const.gbl_One_Time_Timer);
RETURN (NAME_IN (Const.gbl_One_Time_Timer));
END;
PROCEDURE Initialize (P_Event IN VARCHAR2) IS
tm_id timer;
tm_name VARCHAR2 (30) := 'ONE_TIME_TIMER';
BEGIN
tm_id := Find_Timer (tm_name);
IF ID_Null (tm_id) THEN
tm_id := Create_Timer (tm_name, 10, NO_REPEAT);
COPY (p_Event, Const.gbl_One_Time_Timer);
END IF;
END;
END One_Time_Timer;
Der Control-Block (namens "Filter") hat z.B. zwei Items: ENAME und SAL
Erstelle einen WHEN-VALIDATE-ITEM auf ENAME:
BEGIN
One_Time_Timer.Initialize (Const.ott_Query_in_EMP);
END;
letzter Schritt: der EMP-Block benötigt einen PRE-QUERY-Trigger auf Block-Ebene:
BEGIN
IF :Filter.ENAME IS NOT NULL THEN
:EMP.ENAME := :Filter.ENAME;
END IF;
END;
was passiert nun?
Nach dem Ändern eines Wertes in ENAME im FILTER-Block startet der WHEN-VALIDATE-ITEM auf diesem Feld. Er initialisiert den One-Time-Timer. Die globale Variable "global.One_Time_Timer" bekommt den Wert Const.ott_Query_in_EMP zugewiesen (= "Filter EMP-Block"). Danach startet der Timer und feuert nach 10 ms.
10ms später:
Der WHEN-TIMER-EXPIRED startet den execute_query im EMP-block und springt danach zurück auf das Feld, in dem der Cursor stand. Im EMP-block startet der PRE-QUERY und die Daten des EMP-Blocks werden gefiltert durch ":EMP.ENAME := :Filter.ENAME"
das war's schon. Viel Spass damit!
20. Dezember 2006
Undo
Daten aus der Datenbank abfragen und ändern ist in Forms relativ einfach. Aber was ist, wenn der Anwender einen einfachen Undo auf seine Änderungen machen will?
Einfach eine neue Abfrage starten ist der einfachste Weg. Beachtet werden muss:
- in einem Multi-Record-Block muss man sich nach der Abfrage wieder auf dem aktuellen Datensatz positionieren
- wenn die Abfrage durch eine ENTER-QUERY-Selektion geschah kann man nicht zu dem Datensatz springen, da die Abfragemenge unterschiedlich gross ist.
Man muss also eine andere Technik verwenden.
Die Lösung ist diese Funktion. Alle Datenbank-Felder bekommen ihren alten Wert zurück:
Best practice wäre, wenn man diesen Undo vom Menü aus starten könnte (z.B. Bearbeiten - UNDO) oder durch einen Hotkey.
Einfach eine neue Abfrage starten ist der einfachste Weg. Beachtet werden muss:
- in einem Multi-Record-Block muss man sich nach der Abfrage wieder auf dem aktuellen Datensatz positionieren
- wenn die Abfrage durch eine ENTER-QUERY-Selektion geschah kann man nicht zu dem Datensatz springen, da die Abfragemenge unterschiedlich gross ist.
Man muss also eine andere Technik verwenden.
Die Lösung ist diese Funktion. Alle Datenbank-Felder bekommen ihren alten Wert zurück:
PROCEDURE Undo IS
V_Block VARCHAR2 (30) := :SYSTEM.CURSOR_BLOCK;
V_Field VARCHAR2 (61);
V_Item VARCHAR2 (61);
BEGIN
Validate (Item_Scope);
IF :SYSTEM.RECORD_STATUS = 'CHANGED' THEN
V_Field := Get_Block_Property (V_Block, FIRST_ITEM);
V_Item := V_Block || '.' || V_Field;
WHILE V_Field IS NOT NULL
LOOP
IF Get_Item_Property (V_Item, ITEM_TYPE)
IN ('DISPLAY ITEM', 'CHECKBOX', 'LIST',
'RADIO GROUP', 'TEXT ITEM')
AND Get_Item_Property (V_Item, BASE_TABLE) = 'TRUE'
THEN
COPY (Get_Item_Property (V_Item, DATABASE_VALUE),
V_Item);
END IF;
V_Field := Get_Item_Property (V_Item, NextItem);
V_Item := V_Block || '.' || V_Field;
END LOOP;
END IF;
END;
Best practice wäre, wenn man diesen Undo vom Menü aus starten könnte (z.B. Bearbeiten - UNDO) oder durch einen Hotkey.
15. Dezember 2006
Gleich und UnGleich
Manchmal muss man zwei Variablen auf Gleichheit prüfen.
Wenn man einfach nur "IF A = B THEN" schreibt, dann ist das keine Lösung. Falls eine der Variablen NULL ist, dann wird das Ergebnis des Ausdrucks ebenfalls NULL und das IF-Statement interpretiert dies als FALSE. Man benötigt also eine andere Vorgehensweise:
Nun kann man Equal und UnEqual sehr einfach benutzen:
versuch's
Wenn man einfach nur "IF A = B THEN" schreibt, dann ist das keine Lösung. Falls eine der Variablen NULL ist, dann wird das Ergebnis des Ausdrucks ebenfalls NULL und das IF-Statement interpretiert dies als FALSE. Man benötigt also eine andere Vorgehensweise:
FUNCTION Equal (P_String1 IN VARCHAR2,
P_String2 IN VARCHAR2) RETURN BOOLEAN IS
BEGIN
IF P_String1 = P_String2
OR (P_String1 IS NULL AND P_String2 IS NULL) THEN
RETURN (TRUE);
ELSE
RETURN (FALSE);
END IF;
END;
FUNCTION UnEqual (P_String1 IN VARCHAR2,
P_String2 IN VARCHAR2) RETURN BOOLEAN IS
BEGIN
IF P_String1 != P_String2
OR ( P_String1 IS NULL
AND P_String2 IS NOT NULL)
OR ( P_String1 IS NOT NULL
AND P_String2 IS NULL) THEN
RETURN (TRUE);
ELSE
RETURN (FALSE);
END IF;
END;
Nun kann man Equal und UnEqual sehr einfach benutzen:
IF UnEqual (Var1, Var2) THEN
-- do something
ELSE
-- do something different
END IF;
versuch's
5. Dezember 2006
ON-ERROR und ON-MESSAGE-Trigger
Viele Entwickler haben das Problem mit Meldungen, die in der Maske angezeigt werden, zum Beispiel "FRM-40401: No changes to save".
Sie suchen dann nach Workarounds und manipulieren dann oft den :system.message_level:
KEY-COMMIT - Trigger auf Form-Ebene (Quick + Dirty)
oder speichern ihn zwischen:
Das sind keine Best Practices. Diesen Code müsste man in hunderten Prozeduren unterbringen.
Fehler und Meldungen filtern ist die Lösung für ein gutes Message-Handling. Diese Prozedur zeigt die Technik:
ON-ERROR - Trigger auf Form-Ebene
Sie suchen dann nach Workarounds und manipulieren dann oft den :system.message_level:
KEY-COMMIT - Trigger auf Form-Ebene (Quick + Dirty)
BEGIN :System.Message_Level := 25; COMMIT; :System.Message_Level := 5; END;
oder speichern ihn zwischen:
DECLARE V_Message_Level NUMBER; BEGIN V_Message_Level := :System.Message_Level; :System.Message_Level := 25; COMMIT; :System.Message_Level := V_Message_Level; END;
Das sind keine Best Practices. Diesen Code müsste man in hunderten Prozeduren unterbringen.
Fehler und Meldungen filtern ist die Lösung für ein gutes Message-Handling. Diese Prozedur zeigt die Technik:
ON-ERROR - Trigger auf Form-Ebene
DECLARE
V_Error_Code NUMBER;
V_Error_Text VARCHAR2 (2000);
V_DBMS_Error_Code NUMBER;
V_DBMS_Error_Text VARCHAR2 (2000);
BEGIN
V_Error_Code := Error_Code;
V_Error_Text := Error_Text;
V_DBMS_Error_Code := DBMS_Error_Code;
V_DBMS_Error_Text := DBMS_Error_Text;
IF V_Error_Code IN (40401, 40405) THEN
/*
|| 40401, 40405 - no changes to save / apply get filtered
*/
NULL;
ELSIF V_Error_Code IN (-1034, -3114) THEN
/*
|| -1034, -3114 - not connected to database
*/
Message ('Not connect to database, exiting Form');
Exit_Form (no_validate);
ELSIF V_Error_Code IN (40508, 40735)
AND V_DBMS_Error_Code BETWEEN -20999 AND -20000 THEN
/*
|| -20000 errors are raised by RAISE_APPLICATION_ERROR
|| They are handled in a different way
*/
Show_and_Log_DB_Error (V_DBMS_Error_Text);
ELSE
/*
|| All other errors went into Show_and_Log_Error, where they
|| get inspected, analyzed and logged.
*/
Show_and_Log_Error (V_Error_Code);
END IF;
END;
6. November 2006
OOW Zusammenfassung
Dieses Bild zeigt die Howard-Street, während der OOW. Die gesamte Strasse wurde in ein riesiges Zelt verwandelt:


Regis Louis und seine Überblick auf JDeveloper 11g war sehr erfrischend, da das Toolset das Zentrum der neuen Fusion-Technologie wird.

Steven Feuerstein zeigte in seinem Vortrag neue Wege für ein Exception-Handling in PL/SQL und wie man es professionell mit Unit-Testing-Software verbinden kann (wie z.B. utPLSQL).

Sehr interessant war seine Ankündigung, dass er eine neue Software namens Quest Code Tester herausbringen wird, dass den Entwickler beim Erstellen von Test-Fällen für automatisierte PL/SQL-Unittests unterstützt. Erscheinungsdatum in ca. 6 Monaten. Hier ist der Link zu seiner neuen Homepage für all diese Tools:

http://www.toadworld.com/
Bryn Llewellyn (Mit-Erfinder des PL/SQL) zeigte uns in seiner "Meet the Guru"-Stunde die neuen Features von der Oracle Databank 11g.
Am spannendsten ist die neue "edition". D.h. man kann eine neue Version eines Packages / View / Tabelle erzeugen. Mit einem einfachen "alter system set edition = ..." kann man dann zwischen den Versionen wechseln.
Z.B. wenn man eine Reihe von neuen Packages hat und diese auf der Produktions-DB testen will. Diese Packages werden dann in einer Edition erstellt. Danach kann man dann mit obigem Befehl die beiden Versionen wechseln. Das Testen der neuen Package und das Zurücksetzen auf den alten Stand geht in Sekunden!

Das waren die interessantesten Neuerungen auf der Oracle Open World 2006


Regis Louis und seine Überblick auf JDeveloper 11g war sehr erfrischend, da das Toolset das Zentrum der neuen Fusion-Technologie wird.

Steven Feuerstein zeigte in seinem Vortrag neue Wege für ein Exception-Handling in PL/SQL und wie man es professionell mit Unit-Testing-Software verbinden kann (wie z.B. utPLSQL).

Sehr interessant war seine Ankündigung, dass er eine neue Software namens Quest Code Tester herausbringen wird, dass den Entwickler beim Erstellen von Test-Fällen für automatisierte PL/SQL-Unittests unterstützt. Erscheinungsdatum in ca. 6 Monaten. Hier ist der Link zu seiner neuen Homepage für all diese Tools:

http://www.toadworld.com/
Bryn Llewellyn (Mit-Erfinder des PL/SQL) zeigte uns in seiner "Meet the Guru"-Stunde die neuen Features von der Oracle Databank 11g.
Am spannendsten ist die neue "edition". D.h. man kann eine neue Version eines Packages / View / Tabelle erzeugen. Mit einem einfachen "alter system set edition = ..." kann man dann zwischen den Versionen wechseln.
Z.B. wenn man eine Reihe von neuen Packages hat und diese auf der Produktions-DB testen will. Diese Packages werden dann in einer Edition erstellt. Danach kann man dann mit obigem Befehl die beiden Versionen wechseln. Das Testen der neuen Package und das Zurücksetzen auf den alten Stand geht in Sekunden!

Das waren die interessantesten Neuerungen auf der Oracle Open World 2006
26. Oktober 2006
Oracle Open World 2006
Gross, grösser, Moscone! Das ist es, was mir in Erinnerung bleibt, wenn ich an die diesjährige Oracle Open World denke.42000 Besucher waren auf Larry's Konferenz und es wird von Jahr zu Jahr mehr
Larry's Ankündigung in diesem Jahr war: "Wir geben Dir Red Hat Linux-Support, besser als jeder andere im Markt und kostengünstiger".
Seine aktuelle Jacht:
22. Oktober 2006
Ankunft in San Francisco
Gestern startete ich meinen diesjährigen Oracle Open World Trip.
Hier sind einige Impressionen der ersten Nacht. Um 7 Uhr in der Frühe startete der Nike's Woman Marathon in San Francisco am Union Square, direkt vor unserem Hotel.
Die besten Läufer durften schon um 6:40 Uhr starten.
Hier sind einige Impressionen der ersten Nacht. Um 7 Uhr in der Frühe startete der Nike's Woman Marathon in San Francisco am Union Square, direkt vor unserem Hotel.
Die besten Läufer durften schon um 6:40 Uhr starten.
19. Oktober 2006
AOUG Konferenz 2006
Gestern war ich bei der jährlichen österreichischen Oracle User Group in Wien eingeladen.
Kennen sie Wien? Die Stadt ist so liebenswert mit all ihren Burgen und Schlössern, alten Gebäuden und Kaffee-Häusern. Sie würden es lieben.
Mein Vortrag lautete "Oracle Forms 10g und die Kommunikation mit SOA durch BPEL"
Kennen sie Wien? Die Stadt ist so liebenswert mit all ihren Burgen und Schlössern, alten Gebäuden und Kaffee-Häusern. Sie würden es lieben.
Mein Vortrag lautete "Oracle Forms 10g und die Kommunikation mit SOA durch BPEL"
Abonnieren
Posts (Atom)



