Browsing "Older Posts"

APEX-AT-WORK no image

Create your own holiday dvd movie with freeware tools

Von Tobias Arnhold → 11.29.2009
This time my post has nothing to do with APEX nor Oracle.
You all know the situation. You are the one who knows everything about computers, at least thats is the opinion from family and friends. And of course creating a DVD movie from your last holiday should be as easy as a short *snap* with your fingers.
In case you are the one "WHO KNOWS" may this little collection of free picture/sound/video editing tools make your life easier. At least you don't have to google them now. :D

1. Download the pictures/videos from your camera to a local directory
2. Create MPG files from your video files (like AVI, FLV,...). Use the tool: Any Video Converter
3. Create a slideshow movie with DVD slideshow GUI
- Downloads and installs all necessary other tools like Avisynth, Imgburn, Xvid and ffdshow automatically.
- For movies DVD slideshow GUI requires MPG files
- Save the downloaded version of DVD slideshow GUI because it can be so that you wont be able to use your current project in newer versions of the tool.
4. Create a M2V file with ProjectX from your newly created MPG file
5. Create a audio file for your movie with Audacity
5.1 Download some music/sounds from Youtube which fits to your movie with DVDVideoSoft Free Studio Manager - Free Youtube to MP3 converter
5.2 Use the AC3 file which you created with ProjectX (4.)
5.3 At the end create a new AC3 file with Audacity.
5. Merge your newly created video and audio file with ImagoMPEG-Muxer
6. Create a new DVD (with layout and movie files) use GUI for dvdauthor or DVDStyler
- I would recommend to first create ISO images > less DVD trash
- As image loader use Virtual CloneDrive
- As DVD burner use ImgBurn
- As DVD player use VLC media player

Of course the handling will be tricky especially at the beginning. But the result will be a new level of presenting pictures and videos.
APEX-AT-WORK no image

Strange behavior of "No Inline Validation Errors Displayed" check

Von Tobias Arnhold → 11.19.2009
I had two conditional processing checks for one pl/sql process to do. One "No Inline Validation Errors Displayed" check and one "Exist (SQL query returns at least one row)" check.

I thought it would be quite easy to merge it together into a "Exist (SQL query returns at least one row)" condition:

select *
from user_db_links
where UPPER(db_link) = UPPER(:P1_I_INSTANCE_NAME)
and (UPPER(username) not like UPPER(:P1_USERNAME)
or UPPER(host) not like UPPER(:P1_DB_NAME)
or :P1_PASSWORD is not null)
and wwv_flow.g_inline_validation_error_cnt = 0

-- and I tried this AND clause
-- and (select wwv_flow.g_inline_validation_error_cnt from DUAL) = 0

The result was less promising. It just didn't work. The pl/sql process never run with wwv_flow.g_inline_validation_error_cnt in it.

My workaround was to add a new item called :P1_ERROR. I wrote the amount of validation errors into the :P1_ERROR variable inside a pl/sql process which was running before the one I tried the conditional processing with.

-- pl/sql process 1.
...
SELECT wwv_flow.g_inline_validation_error_cnt INTO :P1_ERROR FROM DUAL;
-- or this: :P1_ERROR := wwv_flow.g_inline_validation_error_cnt;
...

-- pl/sql process 2.
select *
from user_db_links
where UPPER(db_link) = UPPER(:P1_I_INSTANCE_NAME)
and (UPPER(username) not like UPPER(:P1_USERNAME)
or UPPER(host) not like UPPER(:P1_DB_NAME)
or :P1_PASSWORD is not null)
and :P1_ERROR = 0

This works without any issues. Maybe one of you know why this happens?

Page refresh button

Von Tobias Arnhold → 11.17.2009
If you want to create a page refresh button inside your APEX page you need to add the following things:

1. Upload a button picture (Shared Components>Images>Create>Upload)
2. Create a new navigation bar (Shared Components>Navigation Bar Entries>Create):
- Image: "LET IT EMPTY!"
- Icon Subtext: <img src="#APP_IMAGES#page_refresh.png" title="Refresh">
- Icon Image Alt: "Refresh"
- Image Height: 40
- Width: 30
- Target type: URL
- URL Target: javascript:window.location.reload(false);

3. Watch the result:
APEX-AT-WORK no image

Ignore sql error messages in pl/sql process

Von Tobias Arnhold → 11.16.2009
Have you experienced the case that you want to execute a process and when a specified error occurs then it should go on like nothing happened.

In my case I had several pl/sql processes and one was to delete a database link. In my special case there shouldn't be an error if no database link exists.

Here is the code snippet for it:

declare
-- error variable
v_no_link EXCEPTION;
-- Map error number returned by raise_application_error to user-defined exception.
PRAGMA EXCEPTION_INIT(v_no_link, -2024);
-- About the error: http://download.oracle.com/docs/cd/B28359_01/server.111/b28278/e1500.htm#sthref1158

begin
-- Drop existing database link
EXECUTE IMMEDIATE 'drop database link ' || UPPER(:P1_I_INSTANCE_NAME);

EXCEPTION
WHEN v_no_link THEN
null;
--WHEN OTHERS THEN
-- raise_application_error(SQLCODE, 'SQLERRM');
end;

More information: PL/SQL User's Guide and Reference - Error Handling

Using the APEX IRR search region

Von Tobias Arnhold → 11.11.2009
Hi all,

The APEX team integrated a nice little region template which mimics the search part of an interactive report. It is called "Report Filter - Single Row". As the name says it has only one row to implement items.

Using one graphical way for searching in your whole application makes life easier for your costumers.

There is just one thing I didn't like on it. The "Search"-icon. To erase it make a copy of the template and erase this part: <img src="#IMAGE_PREFIX#htmldb/builder/builder_find.png" />

The template definition should now look like that:

<table class="apex_finderbar" cellpadding="0" cellspacing="0" border="0" summary="" id="#REGION_STATIC_ID#" #REGION_ATTRIBUTES#>
<tbody>
<tr>
<td class="apex_finderbar_left_top" valign="top"><img src="#IMAGE_PREFIX#1px_trans.gif" width="10" height="8" alt="" class="spacer" alt="" /></td>
<td class="apex_finderbar_middle" rowspan="3" valign="middle"></td>
<td class="apex_finderbar_middle" rowspan="3" valign="middle" style="">#BODY#</td>
<td class="apex_finderbar_left" rowspan="3" width="10"><br /></td>
<td class="apex_finderbar_buttons" rowspan="3" valign="middle" nowrap="nowrap"><span class="apex_close">#CLOSE#</span><span>#EDIT##CHANGE##DELETE##CREATE##CREATE2##COPY##PREVIOUS##NEXT##EXPAND##HELP#</span></td>
</tr>
<tr><td class="apex_finderbar_left_middle"><br /></td></tr>
<tr>
<td class="apex_finderbar_left_bottom" valign="bottom"><img src="#IMAGE_PREFIX#1px_trans.gif" width="10" height="8" class="spacer" alt="" /></td>
</tr>
</tbody>
</table>


At the end it will look similar to that:
APEX-AT-WORK no image

Update of my example application

Von Tobias Arnhold → 10.08.2009
Hi!

Out of some reason Oracle does not provide the applications from the APEX Developer Competition 2009.

Some winners already provided there applications:
Matt Nolan: APEX Plugin Registry Application
Martin Giffy D'Souza: APEX Rules & Guidelines

I just updated my example application as well:

APEX-AT-WORK Developer Competition 2009 Edition
Description: This application is an upgrade of the original APEX-AT-Work Example application. It includes lots of new examples, a new layout, new techniques (like screen casts) and an extended documentation. It is not a normal APEX application which includes lot's of business logic. This application shows how to use the new technologies out there. The core is based on a javascript library called ExtJS. This library creates a completely new look and feel which makes APEX even nicer to use. But also rarely used APEX WEB 2.0 features are integrated based on typical examples.

About the competition:
Oracle.com: Oracle Application Express Developer Competition 2009
David Peake's Blog: Winners of APEX Developer Competition 2009
OTN Blog: Congrats to the Oracle Apex Developer Competition 2009 Winners
Oracle.com: Rules

I must object another behavior what I can't understand. Why aren't there any jury judgments. I really would have loved to know what for example Dimitri thought about my application. I guess all other developers think the same.

Anyway I wish everybody a really exciting OOW.
APEX-AT-WORK no image

Linux bash: Save command and command output in logfile

Von Tobias Arnhold → 10.01.2009
Creating logfiles in a linux environment can be done with > or >> or &> or tee or script but using these commands inside a shell script which should save both the command and the command output becomes really tricky.

With > and >> you just get the command output.
With tee you just get the command output.
With script you get both but it didn't work inside my shell script.

I went on googleling and found a solution:
Capture the command run in the log file

{
set -x
pwd
set +x
} > yourlog.txt 2>&1

I used this small script inside my backup routine:

#!/bin/bash
{
set -x

echo ------------------------------------------------
echo -- - - - - RMAN LEVEL 0 Backup Script - - - - --
echo -- - - - - - - - - - - - - - - - - - - - - - ---
echo -- - - - - Creator: Tobias Arnhold - - - - - ---
echo ------------------------------------------------
echo

echo ------------------------------------------------
echo -- - - - - - - - Start backup - - - - - - - - --
echo ------------------------------------------------
echo

echo -- Set variables
ORACLE_SID=XE
ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
FRA_HOME=/oracle/flash_recovery_area/XE
ORA_SCRIPTS=/oracle/scripts
DATUM=`date +"%Y%m%d%H%M%S"`
echo

echo -- Delete old log files
rm -r $FRA_HOME/backuplog/XE_*
echo

echo -- Start RMAN backup
echo -- See logfile: $FRA_HOME/backuplog/XE_FULL_BACKUP.log
rman target / nocatalog cmdfile=$ORA_SCRIPTS/FULL_BACKUP.sql log=$FRA_HOME/backuplog/XE_FULL_BACKUP.log
echo

echo -- Delete old INIT.ORA files
rm -r $FRA_HOME/initora/*
echo -- Create new INIT.ORA files
cp /oracle/admin/pfile/init.ora $FRA_HOME/initora
echo

... More commands

echo -- Delete empty directories
find $FRA_HOME/backupset -type d -empty -exec rmdir {} \;
echo

echo -- Rename RMAN backup file
cd $FRA_HOME/backuplog/
mv XE_FULL_BACKUP.log XE_FULL_BACKUP.$DATUM.log
mv XE_ARC_BACKUP.log XE_ARC.$DATUM.log
echo

echo ------------------------------------------------
echo -- - - - - - - - Backup finished - - - - - - ---
echo ------------------------------------------------
echo

set +x
} &> /oracle/flash_recovery_area/XE/backuplog/FULL_BACKUP.log
# write log file

# replace all "+ echo" lines inside the log file
LOG_HOME=/oracle/flash_recovery_area/XE/backuplog
sed "/+ echo/d" $LOG_HOME/FULL_BACKUP.log > $LOG_HOME/tmp
mv $LOG_HOME/tmp $LOG_HOME/FULL_BACKUP.log
exit

Now I have a really nice logfile:

------------------------------------------------
-- - - - - RMAN LEVEL 0 Backup Script - - - - --
-- - - - - - - - - - - - - - - - - - - - - - ---
-- - - - - Creator: Tobias Arnhold - - - - - ---
------------------------------------------------

------------------------------------------------
-- - - - - - - - Start backup - - - - - - - - --
------------------------------------------------

-- Set variables
+ ORACLE_SID=XE
+ ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
+ FRA_HOME=/oracle/flash_recovery_area/XE
+ ORA_SCRIPTS=/oracle/scripts
++ date +%Y%m%d%H%M%S
+ DATUM=20090901095244

-- Delete old log files
+ rm -r /oracle/flash_recovery_area/XE/backuplog/XE_FULL_BACKUP-2009-08-31.log

-- Start RMAN backup
-- See logfile: /oracle/flash_recovery_area/XE/backuplog/XE_FULL_BACKUP.log

-- Delete old INIT.ORA files
+ rm -r /oracle/flash_recovery_area/XE/initora/init.ora
-- Create new INIT.ORA files
+ cp /oracle/admin/pfile/init.ora /oracle/flash_recovery_area/XE/initora

... More log informationen

-- Delete empty directories
+ find /oracle/flash_recovery_area/XE/backupset -type d -empty -exec rmdir {} \;
find: /oracle/flash_recovery_area/XE/backupset/2009_08_30: Datei oder Verzeichnis nicht gefunden
find: /oracle/flash_recovery_area/XE/backupset/2009_08_31: Datei oder Verzeichnis nicht gefunden

-- Rename RMAN backup file
+ cd /oracle/flash_recovery_area/XE/backuplog/
+ mv XE_FULL_BACKUP.log XE_FULL_BACKUP.20090901095244.log
+ mv XE_ARC.log XE_ARC.20090901095244.log

------------------------------------------------
-- - - - - - - - Backup finished - - - - - - ---
------------------------------------------------

+ set +x

Hope it can help some of you who are searching for better looking logs.

Upgrade to a journeyman

Von Tobias Arnhold → 9.10.2009
I did it. I finally reached the next level in the Oracle APEX forum:



Ok ok I know that the most APEX experts work much harder inside the forum and they know things I haven't even heard yet. But that is the psychological hurdle to get even further...

Have a nice day.

Tobias
APEX-AT-WORK no image

Data mapping with FlowHeater

Von Tobias Arnhold → 9.07.2009
Do you know this problem you get a csv file and need to import it into your database. Of course with APEX you can use the data load utility (Home>Utilities>Data Load/Unload>Load). But what if you don't have APEX or you need some changes on your import data. Using functions/processes or the SQL*Loader can be quite tricky especially at the beginning or if you haven't worked with it in a while. What if your task become even more difficult. For example: Importing one csv file into oracle, mysql and ms sql database.

There is a nice solution available: Data mapping tools
I am really a fan of visual data mapping tools and want to introduce you into a tool called FlowHeater which can make your life as a database administrator or application developer much easier.

In my example I used a portal version on my USB stick of the FlowHeater (\FlowHeater\BIN).
After I downloaded the Oracle Instant Client driver (10.2.0.4). I created the following batch to run my application:


ECHO off
ECHO Run application FlowHeater
ECHO All settings correlates on the current session inside this batch file

ECHO 1. Variablen setzen
ECHO 1.1 Path Variable
set PATH=D:\instantclient_10_2;%PATH%

ECHO 1.2 ORACLE_HOME Variable
set ORACLE_HOME=D:\instantclient_10_2

ECHO 1.3 TNS_ADMIN Variable
set TNS_ADMIN=D:\instantclient_10_2

ECHO 1.4 NLS_LANG Variable
set NLS_LANG=German_Germany.AL32UTF8

ECHO 2. Open application folder
cd \PortableApps\DATABASE\DATA_MAPPING\FlowHeater

ECHO 3. Run application
\PortableApps\DATABASE\DATA_MAPPING\FlowHeater\FlowHeater.exe


I had one issue running FlowHeater from USB-Stick. It had to do with the Oracle .Net driver and FAT32 file rights. There is an issue where you need the "authenticated user" group with full rights on the oracle home directory. Error: "System.Data.OracleClient requires Oracle Client software version 8.1.7 or greater" There are lots of entries about this error available. That is the reason why my oracle home is now located on volume D:. I didn't want to recreate my whole stick just because of NTFS!

Anyway in case you install the FlowHeater on you PC as normal then no issues like that should occur.

Now watch the flash movie I made:
Data mapping with FlowHeater

Download PDF version: oracle-csv-export.pdf
APEX-AT-WORK no image

APEX navigation concepts

Von Tobias Arnhold → 8.14.2009
Last couple of month I worked on new navigation concepts and wanted to share my ideas and experiences with you.


Download PDF version: APEX_navigation_concepts.pdf

Feel free to share your opinion about APEX navigation concepts!
APEX-AT-WORK no image

Automatic refresh of Interactive reports (IRR)

Von Tobias Arnhold → 8.06.2009
You have maybe heard how to refresh a page within a time period: Page auto refresh
I had the requirement to do this just within an Interactive report (IRR). It was a bit tricky but I could solve it.
Just add the following code into the page header:

<script type="text/javascript">
// automatic reload IRR
function fnc_reloadIRR () {
// start IRR reload
gReport.search('SEARCH');
// repeat search after 30 seconds
window.setTimeout(fnc_reloadIRR, 30000);
};
// start function the first time after 20 seconds
window.setTimeout(fnc_reloadIRR, 20000);
</script>


More details about this solution here: IRR (Interactive report) auto refresh

Update 27.02.2010
Instead of using gReport.search('SEARCH'); you could also try this: gReport.pull();
Here another interesting link about modifying Interactive Reports: Interactive Reports, Handy Tips Part 1
APEX-AT-WORK no image

Dynamic file directories through javascript on page load

Von Tobias Arnhold → 8.03.2009
I fumble around with supporting objects to make my application as portable as possible without any manual scripting. One issue I had discovered had to do with static CSS and JS files provided by frameworks like Ext/YUI or JQuery. I just addressed them hard coded inside my template header:

<html lang="&BROWSER_LANGUAGE.">
<head>
#HEAD#
<title>#TITLE#</title>

<!-- --------------------------------------------------------------------------------- -->
<!-- cascading style sheet file allocation -->
<!-- --------------------------------------------------------------------------------- -->

<!-- apex css integration -->
<link rel="stylesheet" href="#IMAGE_PREFIX#themes/theme_7/theme_3_1.css" type="text/css" />
<!-- extjs css stylesheets -->
<link rel="stylesheet" type="text/css" href="/i/themes/ext-2.0.2/resources/css/ext-all.css" /> -->
<!-- extjs theme -->
<link rel="stylesheet" type="text/css" href="/i/themes/ext-2.0.2/resources/css/xtheme-slate.css" /> -->
<!-- tobias arnhold css integration for extjs -->
<link rel="stylesheet" type="text/css" href="#WORKSPACE_IMAGES#extjs_css_template.css" />
<!-- inidviual css formatatting -->
<!-- forces form to fit screen height -->
<style type="text/css"> #wwvFlowForm {width:100%; height:100%;} </style>

<!-- --------------------------------------------------------------------------------- -->
<!-- javascript file allocation -->
<!-- --------------------------------------------------------------------------------- -->

<!-- extjs js integration -->
<script type="text/javascript" src="/i/themes/ext-2.0.2/adapter/ext/ext-base.js"></script> -->
<script type="text/javascript" src="/i/themes/ext-2.0.2/ext-all.js"></script> -->
<script type="text/javascript" src="/i/themes/ext-2.0.2/ext-all-debug.js"></script> -->
<!-- json integration -->
<script type="text/javascript" src="#APP_IMAGES#json.js"></script>
<!-- global js variables -->
<script type="text/javascript"> var htmldb_Img_Dir = "/i/"; </script>
<!-- extjs template integration by Tobias Arnhold -->
<script type="text/javascript" src="#APP_IMAGES#extjs_js_template_no_tabs.js"></script>
<!-- Own js, css, libs for applciation -->
<script type="text/javascript" src="#APP_IMAGES#aaw_js.js"></script>

</head>
<body #ONLOAD#>
<!-- id="wwvFlowForm"> --> #FORM_OPEN#
...

If you download this application and use other file directories you would need to change all page headers by hand. So I thought how could I make all directories portable (saved inside the database) and automatically be loaded with an application process. I made two examples both worked perfectly with Firefox but IE 8 failed completely.

<!-- --------------------------------------------------------------------------------- -->
<!-- APEX Page Template for ExtJS - No Tabs -->
<!-- by Tobias Arnhold -->
<!-- --------------------------------------------------------------------------------- -->

<html lang="&BROWSER_LANGUAGE.">
<head>
#HEAD#
<title>#TITLE#</title>

<!-- --------------------------------------------------------------------------------- -->
<!-- set ExtJS source directory -->
<!-- --------------------------------------------------------------------------------- -->
<script type="text/javascript">
// set gloabl variables
var v_dir = "http://www.gwt-ext.com/ext/2.0.2";
var v_wi = "#WORKSPACE_IMAGES#";
var v_ai = "#APP_IMAGES#";
var CSS_ext_all;
var CSS_template;
var JS_ext_base;
var JS_ext_all;
var JS_ext_all_debug;
var JS_template;
var JS_aaw;

// add CSS
// add ext-all.css
var v_file= "/resources/css/ext-all.css";
var v_css = v_dir + v_file;
// set variable head
head=document.getElementsByTagName('HEAD')[0];
// next line removes the previously added StyleSheet
if (CSS_ext_all){ head.removeChild(CSS_ext_all); }
CSS_ext_all=document.createElement('LINK');
CSS_ext_all.rel='stylesheet';
CSS_ext_all.type='text/css';
CSS_ext_all.href=v_css;
head.appendChild(CSS_ext_all);

// add extjs_css_template.css
var v_file= "extjs_css_template.css";
var v_css = v_wi + v_file;
// set variable head
head=document.getElementsByTagName('HEAD')[0];
// next line removes the previously added StyleSheet
if (CSS_template){ head.removeChild(CSS_template); }
CSS_template=document.createElement('LINK');
CSS_template.rel='stylesheet';
CSS_template.type='text/css';
CSS_template.href=v_css;
head.appendChild(CSS_template);

// add JS
var v_file= "/adapter/ext/ext-base.js";
var v_js = v_dir + v_file;

// add ext-base.js
head=document.getElementsByTagName('HEAD')[0];

// next line removes the previously added External JavaScript
if (JS_ext_base){ head.removeChild(JS_ext_base); }
JS_ext_base=document.createElement('SCRIPT');
JS_ext_base.type='text/javascript';
JS_ext_base.src=v_js;
head.appendChild(JS_ext_base);

// add JS
// add ext-base.js
var v_file= "/adapter/ext/ext-base.js";
var v_js = v_dir + v_file;
head=document.getElementsByTagName('HEAD')[0];
// next line removes the previously added External JavaScript
if (JS_ext_base){ head.removeChild(JS_ext_base); }
JS_ext_base=document.createElement('SCRIPT');
JS_ext_base.type='text/javascript';
JS_ext_base.src=v_js;
head.appendChild(JS_ext_base);

// add ext-all.js
var v_file= "/ext-all.js";
var v_js = v_dir + v_file;
head=document.getElementsByTagName('HEAD')[0];
// next line removes the previously added External JavaScript
if (JS_ext_all){ head.removeChild(JS_ext_all); }
JS_ext_all=document.createElement('SCRIPT');
JS_ext_all.type='text/javascript';
JS_ext_all.src=v_js;
head.appendChild(JS_ext_all);

// add ext-all-debug.js
v_dir = "/i/themes/ext-2.0.2";
var v_file= "/ext-all-debug.js";
var v_js = v_dir + v_file;
head=document.getElementsByTagName('HEAD')[0];
// next line removes the previously added External JavaScript
if (JS_ext_all_debug){ head.removeChild(JS_ext_all_debug); }
JS_ext_all_debug=document.createElement('SCRIPT');
JS_ext_all_debug.type='text/javascript';
JS_ext_all_debug.src=v_js;
head.appendChild(JS_ext_all_debug);

// add extjs_js_template_no_tabs.js
var v_file= "extjs_js_template_no_tabs.js";
var v_js = v_ai + v_file;
head=document.getElementsByTagName('HEAD')[0];
// next line removes the previously added External JavaScript
if (JS_template){ head.removeChild(JS_template); }
JS_template=document.createElement('SCRIPT');
JS_template.type='text/javascript';
JS_template.src=v_js;
head.appendChild(JS_template);

// add aaw_js.js
var v_file= "aaw_js.js";
var v_js = v_ai + v_file;
head=document.getElementsByTagName('HEAD')[0];
// next line removes the previously added External JavaScript
if (JS_aaw){ head.removeChild(JS_aaw); }
JS_aaw=document.createElement('SCRIPT');
JS_aaw.type='text/javascript';
JS_aaw.src=v_js;
head.appendChild(JS_aaw);
</script>

<!-- --------------------------------------------------------------------------------- -->
<!-- cascading style sheet file allocation -->
<!-- --------------------------------------------------------------------------------- -->

<!-- apex css integration -->
<link rel="stylesheet" href="#IMAGE_PREFIX#themes/theme_7/theme_3_1.css" type="text/css" />

<!-- individual css formatting -->
<!-- forces form to fit screen height -->
<style type="text/css"> #wwvFlowForm {width:100%; height:100%;} </style>

<!-- --------------------------------------------------------------------------------- -->
<!-- javascript file allocation -->
<!-- --------------------------------------------------------------------------------- -->

<!-- json integration -->
<script type="text/javascript" src="#APP_IMAGES#json.js"></script>

<!-- global js variables -->
<script type="text/javascript"> var htmldb_Img_Dir = "/i/"; </script>

</head>
<body #ONLOAD#>
<!-- id="wwvFlowForm"> --> #FORM_OPEN#

And this example which should work with IE. It loads every scripts one by one with 5 seconds in between. If you are more interested take a look into the sources.

<!-- --------------------------------------------------------------------------------- -->
<!-- APEX Page Template for ExtJS - No Tabs -->
<!-- by Tobias Arnhold -->
<!-- Sources: -->
<!-- http://www.phpied.com/dynamic-script-and-style-elements-in-ie/ -->
<!-- http://forum.jswelt.de/javascript/46294-innerhtml-probleme-internet-explorer.html -->
<!-- http://www.phpied.com/javascript-include-ready-onload/ -->
<!-- http://www.phpied.com/javascript-include-ready/ -->
<!-- http://www.phpied.com/javascript-include-ready/#comment-22580 -->
<!-- http://www.javascriptkit.com/javatutors/navigator.shtml -->
<!-- --------------------------------------------------------------------------------- -->

<html lang="&BROWSER_LANGUAGE.">
<head>
#HEAD#
<title>#TITLE#</title>

<!-- --------------------------------------------------------------------------------- -->
<!-- set ExtJS source directory -->
<!-- --------------------------------------------------------------------------------- -->
<script type="text/javascript">
// set gloabl variables
var v_dir = "http://www.gwt-ext.com/ext/2.0.2";
var v_wi = "#WORKSPACE_IMAGES#";
var v_ai = "#APP_IMAGES#";
var CSS_ext_all;
var CSS_template;
var JS_ext_base;
var JS_ext_all;
var JS_ext_all_debug;
var JS_template;
var JS_aaw;

// check browser and start loading files
if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){ //test for MSIE x.x;
var t1 = setTimeout("CSS_ext_all()",5000);
// var t2 = setTimeout("CSS_template()",5000);
// var t3 = setTimeout("JS_ext_base()",5000);
// var t4 = setTimeout("JS_ext_all()",5000);
// var t5 = setTimeout("JS_ext_all_debug()",5000);
// var t6 = setTimeout("JS_template()",5000);
// var t7 = setTimeout("JS_aaw()",5000);
}
else
{
var t1 = CSS_ext_all();
var t2 = CSS_template();
var t3 = JS_ext_base();
var t4 = JS_ext_all();
var t5 = JS_ext_all_debug();
var t6 = JS_template();
var t7 = JS_aaw();
}


// add CSS
function CSS_ext_all() {
// add ext-all.css
var v_file= "/resources/css/ext-all.css";
var v_css = v_dir + v_file;
var html_doc = document.getElementsByTagName('head')[0];
CSS_ext_all = document.createElement('link');
CSS_ext_all.setAttribute('rel', 'stylesheet');
CSS_ext_all.setAttribute('type', 'text/css');
CSS_ext_all.setAttribute('href', v_css);
html_doc.appendChild(CSS_ext_all);
CSS_ext_all.onreadystatechange = function () {
if (CSS_ext_all.readyState == 'complete'|| CSS_ext_all.readyState == 'loaded') {var t2 = setTimeout("CSS_template()",5000);}}
CSS_ext_all.onload = function () {null;}
return true;
}

function CSS_template() {
// add extjs_css_template.css
var v_file= "extjs_css_template.css";
var v_css = v_wi + v_file;
var html_doc = document.getElementsByTagName('head')[0];
CSS_template = document.createElement('link');
CSS_template.setAttribute('rel', 'stylesheet');
CSS_template.setAttribute('type', 'text/css');
CSS_template.setAttribute('href', v_css);
html_doc.appendChild(CSS_template);
CSS_template.onreadystatechange = function () {
if (CSS_template.readyState == 'complete'|| CSS_template.readyState == 'loaded') {var t3 = setTimeout("JS_ext_base()",5000);}}
CSS_template.onload = function () {null;}
return true;
}

// add JS
function JS_ext_base() {
// add ext-base.js
var v_file= "/adapter/ext/ext-base.js";
var v_js = v_dir + v_file;
var html_doc = document.getElementsByTagName('head')[0];
JS_ext_base = document.createElement('script');
JS_ext_base.setAttribute('type', 'text/javascript');
JS_ext_base.setAttribute('src', v_js);
html_doc.appendChild(JS_ext_base);
JS_ext_base.onreadystatechange = function () {
if (JS_ext_base.readyState == 'complete'|| JS_ext_base.readyState == 'loaded') {var t4 = setTimeout("JS_ext_all()",5000);}}
JS_ext_base.onload = function () {null;}
return true;
}
function JS_ext_all() {
// add ext-all.js
var v_file= "/ext-all.js";
var v_js = v_dir + v_file;
var html_doc = document.getElementsByTagName('head')[0];
JS_ext_all = document.createElement('script');
JS_ext_all.setAttribute('type', 'text/javascript');
JS_ext_all.setAttribute('src', v_js);
html_doc.appendChild(JS_ext_all);
JS_ext_all.onreadystatechange = function () {
if (JS_ext_all.readyState == 'complete'|| JS_ext_all.readyState == 'loaded') {var t5 = setTimeout("JS_ext_all_debug()",5000);}}
JS_ext_all.onload = function () {null;}
return true;
}
function JS_ext_all_debug() {
// add ext-all-debug.js
v_dir = "/i/themes/ext-2.0.2";
var v_file= "/ext-all-debug.js";
var v_js = v_dir + v_file;
var html_doc = document.getElementsByTagName('head')[0];
JS_ext_all_debug = document.createElement('script');
JS_ext_all_debug.setAttribute('type', 'text/javascript');
JS_ext_all_debug.setAttribute('src', v_js);
html_doc.appendChild(JS_ext_all_debug);
JS_ext_all_debug.onreadystatechange = function () {
if (JS_ext_all_debug.readyState == 'complete'|| JS_ext_all_debug.readyState == 'loaded') {var t6 = setTimeout("JS_template()",5000);}}
JS_ext_all_debug.onload = function () {null;}
return true;
}
function JS_template() {
// add extjs_js_template_no_tabs.js
var v_file= "extjs_js_template_no_tabs.js";
var v_js = v_ai + v_file;
var html_doc = document.getElementsByTagName('head')[0];
JS_template = document.createElement('script');
JS_template.setAttribute('type', 'text/javascript');
JS_template.setAttribute('src', v_js);
html_doc.appendChild(JS_template);
JS_template.onreadystatechange = function () {
if (JS_template.readyState == 'complete'|| JS_template.readyState == 'loaded') {var t7 = setTimeout("JS_aaw()",5000);}}
JS_template.onload = function () {null;}
return true;
}
function JS_aaw() {
// add aaw_js.js
var v_file= "aaw_js.js";
var v_js = v_ai + v_file;
var html_doc = document.getElementsByTagName('head')[0];
JS_aaw = document.createElement('script');
JS_aaw.setAttribute('type', 'text/javascript');
JS_aaw.setAttribute('src', v_js);
html_doc.appendChild(JS_aaw);
JS_aaw.onreadystatechange = function () {
if (JS_aaw.readyState == 'complete'|| JS_aaw.readyState == 'loaded') {null;}}
JS_aaw.onload = function () {null;}
return true;
}
</script>
<!-- --------------------------------------------------------------------------------- -->
<!-- cascading style sheet file allocation -->
<!-- --------------------------------------------------------------------------------- -->

<!-- apex css integration -->
<link rel="stylesheet" href="#IMAGE_PREFIX#themes/theme_7/theme_3_1.css" type="text/css" />

<!-- individual css formatting -->
<!-- forces form to fit screen height -->
<style type="text/css"> #wwvFlowForm {width:100%; height:100%;} </style>

<!-- --------------------------------------------------------------------------------- -->
<!-- javascript file allocation -->
<!-- --------------------------------------------------------------------------------- -->

<!-- json integration -->
<script type="text/javascript" src="#APP_IMAGES#json.js"></script>

<!-- global js variables -->
<script type="text/javascript"> var htmldb_Img_Dir = "/i/"; </script>

</head>
<body #ONLOAD#>
<!-- id="wwvFlowForm"> --> #FORM_OPEN#

IE errors:
Details zum Fehler auf der Webseite
Benutzer-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Zeitstempel: Mon, 3 Aug 2009 11:20:49 UTC
Meldung: 'null' ist Null oder kein Objekt
Zeile: 13
Zeichen: 707
Code: 0
URI: http://:8080/i/themes/ext-2.0.2/ext-all.js

Meldung: 'null' ist Null oder kein Objekt
Zeile: 1555
Zeichen: 13
Code: 0
URI: http://:8080/i/themes/ext-2.0.2/ext-all-debug.js

Interesting behavior in example two: When I reload the page after I got these errors it works but when I then click onto another leaf IE crashes completely. For now I have enough...

Issue with packed app and javascript files (text/x-c)

Von Tobias Arnhold → 7.10.2009
I had the pleasure to find either an APEX bug or to find out that I'm unable to create packed applications! :O

After I installed my example application from http://apex.oracle.com/ on my local machine. I got a strange error after I edited an automatic installed javascript file:
The resource from this URL is not text: http://#SERVER_NAME#:8080/apex/wwv_flow_file_mgr.get_file?p_security_group_id=4257722764435732&p_flow_id=12000&p_fname=json.js



I checked the file again and found out that the "mime type" changed to: text/x-c
Normally it is: text/x-js

I uploaded/replaced a couple of installed javascript files to show you the difference:

All installed javascript files got this new mime type and they all worked properly until I changed something inside these files (in APEX).
As you see html and sql files got the right mime type even after the import.

Is this a known issue? Did I export and import something wrong?

I use the newest version of APEX 3.2 inside a XE database.
APEX-AT-WORK no image

DBMS_SCHEDULER examples

Von Tobias Arnhold → 6.25.2009
May be interesting to some of you which haven't had the time testing and working with the DBMS_SCHEDULER. I collected some examples to show what is possible with that amazing tool.

DBMS_SCHEDULER is an internal Oracle package (since Version 10g) which provides database driven jobs.
It's divided into 3 parts:
  • Time schedule part - dbms_scheduler.create_schedule
  • Program declaration part - dbms_scheduler.create_program
  • Job (conflation) part -dbms_scheduler.create_job
Examples of the dbms_scheduler.create_schedule part:

begin
-- daily from Monday to Sunday at 22:00 (10:00 p.m.)
dbms_scheduler.create_schedule
(schedule_name => 'INTERVAL_DAILY_2200',
start_date=> trunc(sysdate)+18/24, -- start today 18:00 (06:00 p.m.)
repeat_interval=> 'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI,SAT,SUN; BYHOUR=22;',
comments=>'Runtime: Every day (Mon-Sun) at 22:00 o'clock');

-- run every hour, every day
dbms_scheduler.create_schedule(
schedule_name => 'INTERVAL_EVERY_HOUR',
start_date => trunc(sysdate)+18/24,
repeat_interval => 'freq=HOURLY;interval=1',
comments => 'Runtime: Every day every hour');

-- run every 5 minute, every day
dbms_scheduler.create_schedule(
schedule_name => 'INTERVAL_EVERY_5_MINUTES',
start_date => trunc(sysdate)+18/24,
repeat_interval => 'freq=MINUTELY;interval=5',
comments => 'Runtime: Every day all 5 minutes');

-- run every minute, every day
dbms_scheduler.create_schedule(
schedule_name => 'INTERVAL_EVERY_MINUTE',
start_date => trunc(sysdate)+18/24,
repeat_interval => 'freq=MINUTELY;interval=1',
comments => 'Runtime: Every day every minute');

-- run every Sunday at 18:00 (06:00 p.m.)
dbms_scheduler.create_schedule
(schedule_name => 'INTERVAL_EVERY_SUN_1800',
start_date=> trunc(sysdate)+18/24,
repeat_interval=> 'FREQ=DAILY; BYDAY=SUN; BYHOUR=18;',
comments=>'Runtime: Run at 6pm every Sunday');
end;

Example of the dbms_scheduler.create_program part:

begin
-- Call a procedure of a database package
dbms_scheduler.create_program
(program_name=> 'PROG_COLLECT_SESS_DATA',
program_type=> 'STORED_PROCEDURE',
program_action=> 'pkg_collect_data.prc_session_data',
enabled=>true,
comments=>'Procedure to collect session information'
);
end;

Example of the dbms_scheduler.create_job part:

begin
-- Connect both dbms_scheduler parts by creating the final job
dbms_scheduler.create_job
(job_name => 'JOB_COLLECT_SESS_DATA',
program_name=> 'PROG_COLLECT_SESS_DATA',
schedule_name=>'INTERVAL_EVERY_5_MINUTES',
enabled=>true,
auto_drop=>false,
comments=>'Job to collect data about session values every 5 minutes');
end;

Examples to change dbms_scheduler settings:

begin
-- change start time
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => 'INTERVAL_EVERY_5_MINUTES',
attribute => 'start_date',
value => to_date('22.06.2009 12:15','dd.mm.yyyy hh24:mi')
);

-- change repeat interval
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => 'INTERVAL_EVERY_MINUTE',
attribute => 'repeat_interval',
value => 'freq=MINUTELY;interval=2'
);
end;

Example to run job immediate:

begin
dbms_scheduler.run_job('JOB_COLLECT_SESS_DATA',TRUE);
end;

Example to restart job:

begin
dbms_scheduler.disable('JOB_COLLECT_INST_INFO');
dbms_scheduler.enable('JOB_COLLECT_INST_INFO');
end;

Select job status:

-- All jobs
select * from user_scheduler_jobs;

-- Get information to job
select * from user_scheduler_job_log order by log_date desc;

-- Show details on job run
select * from user_scheduler_job_run_details;


Further information about the DBMS_SCHEDULER:
http://psoug.org/reference/OLD/dbms_scheduler.html
Oracle documentation about the DBMS_SCHEDULER

These scripts are tested in an Oracle XE environment (10.2.0.1).
I will extend this post whenever I need new scripts.

Update 11.09.2010:

Run a job without program and schedule plan (all in one command):

dbms_scheduler.create_job (
job_name => 'TEST_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'begin /* some process code */ commit; end;',
number_of_arguments => 0,
start_date => sysdate +1/24/59, -- sysdate + 1 minute
job_class => 'ADMIN', -- Priority Group
enabled => TRUE,
auto_drop => TRUE,
comments => 'Testrun');


@Sue
Dynamic Scheduled jobs from inside APEX are no problem. But be careful if you use "execute immediate"!
APEX-AT-WORK no image

ExtJS navigation tree

Von Tobias Arnhold → 6.19.2009
Hi folks,

I added an ExtJS navigation tree to my example application. To get the JSON data out of the database I created a small package which is dynamically creating this data string on every page load.

Take a look at the updated source code: AAW - ExtJS navigation tree

I got some request about the application installation file (application source code). So I decided to publish it to everybody how asks for it via email: tobias-arnhold@hotmail.de
I would use the same procedure as Denes does. You get an developer account and can download the current version yourself.

PS, feedback is always welcome! :D
APEX-AT-WORK no image

Several Interactive Reports in one ExtJS page

Von Tobias Arnhold → 6.11.2009
I created an example page for the ExtJS layout http://apex.oracle.com/pls/otn/f?p=65555 based on the solution of Roel Hartman "Using two Interactive Reports on one page"
Just follow the tree link: "Integrate IRs into one ExtJS page"

I encountered a problem when I accessed the example page with IE8. After the first page load the following error could occur:
ORA-00001: unique constraint
(APEX_030200.WWW_FLOW_COLLECTION_MEMBERS_PK) violated
After another reload the error disappears and the application works fine.

It's time for a new revolution - Update of my example app

Von Tobias Arnhold → 6.09.2009
For those who are interested in APEX, ExtJS and AJAX take a look on my new/updated example application:
http://apex.oracle.com/pls/otn/f?p=65555

Feel welcome to post some feedback!



I don't know if you have noticed it yet? ;D I updated my blog layout as well.

Building your own button in an APEX region

Von Tobias Arnhold → 5.29.2009
Have you ever experienced some issues when you wanted to create a button inside an APEX region behind an item and that button should call a javascript function.
With normal APEX features "Create a button displayed among this region's items" it's not possible as I know because APEX creates automatically a doSubmit button.

Anyway one way to fix that is to create an own button:

First create your own button, for example on:
http://www.buttongenerator.com/
or on:
http://www.buttonboost.com

Next upload the new button image into the application workspace.
Home>Application Builder>Application 100>Shared Components>Images>Create>
Application: #Your application name#
Upload New Image: #Image path#
Notes: #Additional information to the picture#

Last step is to create an "Display as Text" page item with the following settings:
Label: empty
Template: No Label
Width: 0
Post Element Text:

&nbsp;
<img
id="P1_btnID1"
src="#APP_IMAGES#start.png"
// if image was set to
// "No Application Associated"
// then use #WORKSPACE_IMAGES#
alt="Set user settings"
onclick="fnc_setUser('P1_USER')"
style="cursor: pointer"
title="Set user settings"
>

Info: If the button should be right behind an item then edit the option "Begin On
New Line" to "No".
And of course you can put the img-tag also into the "Post Element Text" of an already used APEX item.

At the end it should look similar to that:

ORA-07445 _npierr+487 error in APEX runinng under a XE database

Von Tobias Arnhold → 5.15.2009
I created a dynamic pl/sql report where the select was based on an external table (transcribed through a database link).

DECLARE
v_query varchar2(1000);
BEGIN
IF :P1_INSTANCE_NAME is not null THEN
v_query := 'SELECT NAME,
VALUE,
isdefault,
isses_modifiable,
issys_modifiable,
ismodified,
isadjusted,
description
FROM v$parameter@'||:P1_INSTANCE_NAME;
ELSE
v_query := 'SELECT 1 FROM dual WHERE 1=0';
END IF;
return(v_query);
END;

Tip: If you are more interested into dynamic reports! Then here comes a really handy explanation:
http://www.apex-blog.com/oracle-apex/dynamic-report-regions-tutorial-32.html

After the login into the APEX application builder a strange download error occurred. When I clicked on a APEX link a download window opened and showed the following arguments:


At the same time when the error occurred the following entries in the alertlog file got created:

Fri May 15 13:14:43 2009
Errors in file c:\oracle\admin\xe\bdump\xe_s000_1436.trc:
ORA-07445: exception encountered: core dump [ACCESS_VIOLATION] [_npierr+487] [PC:0x5F22C3] [ADDR:0x4] [UNABLE_TO_READ] []

Fri May 15 13:15:27 2009
found dead shared server 'S000', pid = (14, 2)
Fri May 15 13:17:07 2009
Errors in file c:\oracle\admin\xe\bdump\xe_s002_2492.trc:
ORA-07445: exception encountered: core dump [ACCESS_VIOLATION] [_npierr+487] [PC:0x5F22C3] [ADDR:0x4] [UNABLE_TO_READ] []

Fri May 15 13:17:24 2009
found dead shared server 'S002', pid = (16, 1)

I looked in Metalink, the Oracle forum and the web itself and came to the following conclusion:
That error occurs when you call a database link in a web application. There is no official workaround at least no one for the XE database. It should be patched in the following Oracle database versions: 11.2, 11.1.0.6.P11

Another hint came from the Oracle forum. They meant you should set up your browser to "en-us" language. I tried it but it didn't help either.
Anyway I created a application with German language so it wouldn't be such a good hotfix. ;D

My workaround:
Creating a new table where I import the information before via a pl/sql package and the dbms scheduler. It's not really what I wanted but the only way for now.

Here are the web links I rallied to it:
Metalink note: 6798427.8
Metalink note: 809366.1
Metalink bug no.: 6798427
XE forum: Beta 3 Bug: using database link freezes apex and xdb
XE forum: Universal edition choke on en-GB browser, core dumped, ORA-07445, _npierr+4
APEX forum: page not found, ORA-07445: exception encountered: core dump

Update 22.06.2009
I had the idea to use a function selecting the external data (with execute immediate) and save this data into a temporary table.
Then I created a new APEX "Before Header Process" and called this database function and made a select into my page variables.
But I still get this error... I give up!
APEX-AT-WORK no image

Outlook calendar in APEX

Von Tobias Arnhold → 4.17.2009
Hi,
if you want to integrate your outlook calendar or some other oultook features into an APEX site use the following code in a HTML region.

<DIV STYLE="width:800px;height:400px">
<OBJECT classid=CLSID:0006F063-0000-0000-C000-000000000046
id=ViewCtlFolder
width="100%"
height="100%"
Codebase="http://activex.microsoft.com/activex/controls/office/outlctlx.CAB#ver=9,0,0,3203">
<param name="Namespace" value="MAPI">
<param name="Folder" value="Calendar">
<param name="Restriction" value="">
<param name="DeferUpdate" value="0">
</OBJECT>
</DIV>

Example page: http://apex.oracle.com/pls/otn/f?p=28737:8
More information to that topic:
http://blogs.tech-recipes.com/shamanstears/2008/04/15/outlook-creating-your-own-outlook-today-page/
http://www.outlookcode.com

That feature is just appropriable with the Internet Explorer.

Spacing APEX items

Von Tobias Arnhold → 3.13.2009
Did you ever experienced the problem when you have a couple of items in the same line/row in a HTML region and you have a select list (in the next row) which becomes so Hugh that the upper items places more and more to the right. It just looks ugly and the select list value
normally changes dynamically.
What to do?
First we need to bring a logical barrier in between the line breaks.
Using a "Stop and Start HTML Table" object in between text items and select list.
It will look like that:
Result: Just the text label is incorrect anymore.Now we have two choices:1. Using &nbsp object until it fits.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Text1:&nbsp;
Problem: The more text different there are, the more &nbsp you will need.

2. Creating a SPACER item
Create a new display only item called :P1_SPACER in front of the first text item.Now add the following text under "Element Table Cell Attributes" > style="width:200px"Edit the pixel value so that it fits into your page.

The region items will be listed like that:
In case you still have some problem with different browser presentations look at my last post.

Update 17.03.2009:
Just tested a really good hint from Patrick.
Using the ColSpan option in the select list item saves all other steps above. Set the value for ColSpan (in my case) to 3 and the same result appears. Good that I never stop learning...

Own browser check condition in APEX

Von Tobias Arnhold → 3.12.2009
The easiest way to check the browser type for conditional displaying
is to use one of the following conditions:
  • Client Browser: Mozilla, Netscape 6.x/7x or higher
  • Client Browser: Microsoft Internet Explorer 5.5,6.0 or higher
  • Client Browser: Other browsers (or older version)
That way is definitely the easiest one. But in case you have several display conditions you need to check or you want to use that check at another point (for example inside an pl/sql script) then you get some trouble.
I asked in the APEX forum for help and thanks to Andy he gave me a really good hint how to find a solution for that issue.
Forum link: http://forums.oracle.com/forums/message.jspa?messageID=3322457

In my case I wanted to use a condition inside the SQL statement of an updateable report. Because FF and IE displayed the report columns differently.

First I followed the hint from Andy and analyzed the OWA_UTIL output with the function PRINT_CGI_ENV().

BEGIN
OWA_UTIL.PRINT_CGI_ENV();
END;

The result for parameter HTTP_USER_AGENT (with FF) looks like that:

HTTP_USER_AGENT = Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7 (.NET CLR 3.5.30729)

Next step was to get that output text into a variable. Function OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT') provides the information.
I created a variable called :P1_BROWSER_TYPE and an initialization process to save the information in my variable.

IF :P1_BROWSER_TYPE NULL THEN
IF OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT') LIKE '%MSIE 7.0%' THEN
:P1_BROWSER_TYPE := 'IE7';
ELSIF OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT') LIKE '%MSIE 6.0%' THEN
:P1_BROWSER_TYPE := 'IE6';
ELSIF OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT') LIKE '%Firefox/3%' THEN
:P1_BROWSER_TYPE := 'FF3';
ELSIF OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT') LIKE '%Firefox/2%' THEN
:P1_BROWSER_TYPE := 'FF2';
ELSIF OWA_UTIL.GET_CGI_ENV('HTTP_USER_AGENT') LIKE '%Firefox/1%' THEN
:P1_BROWSER_TYPE := 'FF1';
ELSE
:P1_BROWSER_TYPE := 'UNKNOWN';
END IF;
END IF;

Now I created my updateable report with a CASE WHEN CHECK inside the SQL statement:

SELECT CASE :P1_BROWSER_TYPE WHEN 'FF3' THEN '<b><div style="width: 289px">Sum:</div></b>'
WHEN 'FF2' THEN '<b><div style="width: 289px">Sum:</div></b>'
WHEN 'FF1' THEN '<b><div style="width: 289px">Sum:</div></b>'
WHEN 'IE7' THEN '<b><div style="width: 247px">Sum:</div></b>'
WHEN 'IE6' THEN '<b><div style="width: 247px">Sum:</div></b>'
ELSE '<b><div style="width: 247px">Sum:</div></b>' END as "Sum",
...
Example app: http://apex.oracle.com/pls/otn/f?p=28737:7
Documentation link for the OWA_UTIL package: http://download-west.oracle.com/docs/cd/B12037_01/appdev.101/b10802/w_util.htm#997271
APEX-AT-WORK no image

Terrific Oracle forum exemplified by "wi (dd.mm.yyyy-dd.mm.yyyy)"

Von Tobias Arnhold → 2.20.2009
Did you ever had any problems with Oracle based issues like Database, APEX, Forms, SQL and so on? Of course you had.
Normally the Oracle Metalink is the first address for everybody who has a contract with Oracle. But in some cases the Oracle forum help is unbeatable.
What I mean is. Whenever you have a problem with SQL commands or APEX issues the fastest way to find a solution is to ask in the Oracle forums.

I want to bring up a special example I had. I needed some week and date values via a sql command for a month like that:
wi (dd.mm.yyyy-dd.mm.yyyy)
05 (01.02.2009-01.09.2009)
06 (02.02.2009-08.09.2009)
07 (09.02.2009-15.09.2009)
08 (16.02.2009-22.09.2009)
09 (23.02.2009-28.09.2009)

I couldn't fix it myself so I wrote a forum entry:
http://forums.oracle.com/forums/message.jspa?messageID=2842808
I got more then a tip I got a solution for the problem.

A couple of weeks later I just found out that the last week in February was missing. So I wrote a new post which was answered just a couple of hours later.
http://forums.oracle.com/forums/message.jspa?messageID=3279392

I think this type of help is sometimes more valuable then any GOLD support you can get. :D

By the way here is the solution for the problem: ;D

-- select all weeks for a year
select to_char(dt+(7*rn),'WW') ||' ('||
to_char(dt+(decode(rn,0,0,(7*rn)+1-offset))) ||'-'||
case when dt+(7*(rn+1))-offset > last_day(dt) then
last_day(dt) ||')'
else
dt+(7*(rn+1))-offset ||')'
end as show_value,
to_char(dt+(7*rn),'WW') as return_value
from (select to_date(mes||'2009','MMYYYY') as dt, to_number(to_char(to_date(mes||'2009','MMYYYY'),'D')) as offset
from dual, (select to_char(rownum, '00') mes from dual connect by rownum <= 12))
,(select rownum-1 rn from dual connect by rownum <= 6)
where trunc(to_date(dt+(decode(rn,0,0,(7*rn)+1-offset))), 'MM') = dt
order by dt, return_value asc
-- select all week for a month
select to_char(dt+(7*rn),'IW') ||' ('||
to_char(dt+(decode(rn,0,0,(7*rn)+1-offset))) ||'-'||
case when dt+(7*(rn+1))-offset > last_day(dt) then
last_day(dt) ||')'
else
dt+(7*(rn+1))-offset ||')'
end as show_value,
to_char(dt+(7*rn),'IW') as return_value
from (select to_date(02||2009,'MMYYYY') as dt from dual)
,(select to_number(to_char(to_date(02||2009,'MMYYYY'),'D')) as offset from dual)
,(select rownum-1 rn from dual connect by rownum <= 5)
where trunc(to_date(dt+(decode(rn,0,0,(7*rn)+1-offset))), 'MM') = dt
-- the way I use it in APEX
select to_char(dt+(7*rn),'IW') ||' ('||
to_char(dt+(decode(rn,0,0,(7*rn)+1-offset))) ||'-'||
case when dt+(7*(rn+1))-offset > last_day(dt) then
last_day(dt) ||')'
else
dt+(7*(rn+1))-offset ||')'
end as show_value,
to_char(dt+(7*rn),'IW') as return_value
from (select to_date(:P1_MONTH||:P1_YEAR,'MMYYYY') as dt from dual)
,(select to_number(to_char(to_date(:P1_MONTH||:P1_YEAR,'MMYYYY'),'D')) as offset from dual)
,(select rownum-1 rn from dual connect by rownum <= 5)
where trunc(to_date(dt+(decode(rn,0,0,(7*rn)+1-offset))), 'MM') = dt

Special thanks to BluShadow and Miguel Chillitupa!
APEX-AT-WORK no image

Set up column width in an APEX report (for Firefox)

Von Tobias Arnhold → 2.13.2009
Most of you would say: "Why is that so special? Just go to
Report Attributes>Column Attributes>Column Formatting>CSS Style and add for example: width:100px"

Like the help says:
"Use this attribute to apply a style to a column value. For example, setting this attribute to 'color:#FF0000;' will result in the following html being generated:
<span style="color:#FF0000">Sample Data</span>
This will change the text color of the column to red."

You all are right but there is a problem with Firefox which is ignoring this setting.
Why? Take a look here:
http://www.velocityreviews.com/forums/t163666-firefox-ignores-the-style-width-attribute-in-the-span-tag.html

How to fix that now? I use the div tag in my sql statement for the report:

SELECT '<b><div style="width: 150px; text-align: left">Employee no.: ' || "EMP"."EMPNO" ||
'</div></b>' as "EMPNO",
'<div style="border: 1px solid rgb(204, 204, 204); padding: 2px; width: 150px; background-color: rgb(225, 225, 225); text-align: center">' ||
"EMP"."ENAME" || '</div>' as "ENAME",
'<div style="border: 1px solid rgb(204, 204, 204); padding: 2px; width: 100px; background-color: rgb(225, 225, 225); text-align: center">' ||
"EMP"."HIREDATE" || '</div>' as "HIREDATE",
'<div style="border: 1px solid rgb(204, 204, 204); padding: 2px; width: 100px; background-color: rgb(225, 225, 225); text-align: center">' ||
"EMP"."SAL" || '</div>' as "SAL",
'<div style="border: 1px solid rgb(204, 204, 204); padding: 2px; width: 100px; background-color: rgb(225, 225, 225); text-align: center">' ||
"EMP"."COMM" || '</div>' as "COMM"
FROM "EMP"
-- </div> - div tag is needed to create the css style attributes
-- "width: 150px;" - for column width
-- "text-align: left" - for text alignment
-- "background-color: rgb(225, 225, 225)" - for column background color
-- "border: 1px solid rgb(204, 204, 204)" - for border color
-- "padding: 2px" - for empty place between text and border


Example application in action: http://apex.oracle.com/pls/otn/f?p=25472:30

Forum entry to it: http://forums.oracle.com/forums/thread.jspa?forumID=137&threadID=854151

Honestly I think there is another way to fix this issue which I don't know yet but I would really appreciate to get to know about it. :D

To all: Enjoy the weekend, have fun and DON'T think about the world economic crisis. :)
APEX-AT-WORK no image

Focus problem with IE6 and APEX_ITEM.SELECT_LIST_FROM_LOV

Von Tobias Arnhold → 2.12.2009
If you are using the SELECT_LIST_FROM_LOV item in your apex reports you may have noticed that you can get some trouble with the Internet Explorer 6.

For example your report includes 100 rows which are all displayed on one page and you must scroll up and down to reach all items. In case you have the focus on one of your select list items and set it from value x to y and immediately after that you want to scroll down. The cursor stays in the item and scrolls inside instead of outside the page.

This behavior just appears with IE6 all newer browser works after a standard behavior. After you selected an item value and you start scrolling, the page scrolls after your mouse movement.

How to fix this issue with IE6? You need to edit your SQL select statement for your report:

-- select statement with IE6 problems
select
b_id as "Book number",
'<b>'||b_name||'</b>' ||
' (' || b_description || ') ' as "Book name"
apex_item.SELECT_LIST_FROM_LOV(
1, -- p_idx
b_category_id, -- p_value
'LOV_BOOK_CATEGORIES', -- p_lov
'', -- p_attributes
'YES', -- p_show_null
'', -- p_null_value
'no book category selected', -- p_null_text
'', -- p_item_id
'' -- p_item_label)
as "Book category"
from books;

-- fixed select statement with attribute for wrong focus behavior
select
b_id as "Book number",
'<b>'||b_name||'</b>' ||
' (' || b_description || ') ' as "Book name"
apex_item.SELECT_LIST_FROM_LOV(
1, -- p_idx
b_category_id, -- p_value
'LOV_BOOK_CATEGORIES', -- p_lov
'onChange="body.focus()"', -- p_attributes
'YES', -- p_show_null
'', -- p_null_value
'no book category selected', -- p_null_text
'', -- p_item_id
'' -- p_item_label)
as "Book category"
from books;

You need to use onChange="body.focus()" in the attribute section.

Of course you can also use this functionality in a normal select list item.
Go Edit Page Item>Element>HTML Form Element Attributes
and add: onChange="body.focus()"
APEX-AT-WORK no image

Administration and development tools I work with

Von Tobias Arnhold → 2.09.2009
Hi all!
I wrote a lot about APEX the last couple of month. Now I want to write about the tools/applications I use to get these apps running and having always the full grip over it.

What main points should an application including to be usable in my eyes?
  • It should work for what I bought it "no more, no less"
  • It should be fast (During start up and use)
  • It should be always accessible better portable (like on an usb stick)
  • It should be intuitive and easy to use
  • It shouldn't cost to much (I mean thousands of €uros) or better be freeware or open source
Database administration tools:
Monitoring
  • LAB128 (Commercial) - One of the jewels: it fits to all main points I wrote before
Log file analysis
  • OraSentry (Charityware) - Small tool which shows you if your alertlog/database is in trouble
SQL and PL/SQL development tools:
  • PL/SQL Developer (Commercial) - In my eyes the best development tool for pl/sql programming
  • TORA (GPL) - This one (a tool with a long history) needs to be named too.
Database modeling tools:
  • DBSchema (Commercial) - A really good mix between price and performance
  • Schemester (Freeware) - I liked this one a lot unfortunately its not longer under development
Data mapping:
  • FlowHeater (Commercial) - A really good data mapping tool for an unbeatable price. It is still under development and unfortunately (until now) only in German available
HTML, CSS and JS development:
  • Notepad++ (GPL) - A must have for fast and easy programming
Website debugging tools:
  • Firefox - Of course a must have for all APEX developers
With these add ons:
  • Colorzilla
  • Firebug
  • Greasemonkey
  • IE Tab
  • Resizeable Textarea
  • Web Developer
Have fun trying them out and maybe some of you know other really good tools. Real jewels for the apex development community.

And of course I just write about them because I like them (and paid for them) and not because they paid for me. :D
APEX-AT-WORK no image

Audit trail in APEX

Von Tobias Arnhold → 1.31.2009
In case you have the requirement to use audit trail functionality in your APEX application then look at that example:

First we need two tables:
- The orignial table (BOOKS)
- The audit trail table (AUDIT_BOOKS)

-- the orignial table (BOOKS)
create table BOOKS
(
B_ID NUMBER not null,
B_NAME VARCHAR2(100),
B_DESCRIPTION VARCHAR2(500)
);

-- the audit trail table (AUDIT_BOOKS) always
-- includes 3 more columns for the user, the date
-- and the action (delete, update, insert)
-- this table shouldn't include any PK or FK
create table AUDIT_BOOKS
(
B_ID NUMBER not null,
B_NAME VARCHAR2(100),
B_DESCRIPTION VARCHAR2(500),
AUDIT_USER VARCHAR2(50),
AUDIT_DATE DATE,
AUDIT_ACTION VARCHAR2(6)
);

Next step is to create a trigger which includes the audit trail functionality:

CREATE OR REPLACE TRIGGER trg_audit_books
-- starts on every update, insert or delete command
AFTER INSERT OR DELETE OR UPDATE ON books
FOR EACH ROW
DECLARE
-- variable which declares if update, delete or insert process
v_trg_action VARCHAR2(6);
BEGIN
IF updating
THEN
-- when update
v_trg_action := 'UPDATE';
ELSIF deleting
THEN
-- when delete
v_trg_action := 'DELETE';
ELSIF inserting
THEN
-- when insert
v_trg_aktion := 'INSERT';
ELSE
-- if something else
v_trg_action := NULL;
END IF;

IF v_trg_action IN ('DELETE','UPDATE') THEN
-- if v_trg_action is DELETE or UPDATE then insert old table values
INSERT INTO audit_books
( B_ID, B_NAME, B_DESCRIPTION,
AUDIT_USER, AUDIT_DATE, AUDIT_ACTION)
VALUES
(:OLD.B_ID, :OLD.B_NAME, :OLD.B_DESCRIPTION,
UPPER(v('APP_USER')), SYSDATE, v_trg_action);
ELSE
-- if v_trg_action is INSERT then insert new table values
INSERT INTO audit_books
( B_ID, B_NAME, B_DESCRIPTION,
AUDIT_USER, AUDIT_DATE, AUDIT_ACTION)
VALUES
(:NEW.B_ID, :NEW.B_NAME, :NEW.B_DESCRIPTION,
UPPER(v('APP_USER')), SYSDATE, v_trg_action);
END IF;
-- about the insert command on the audit table
-- for current apex user: v('APP_USER')
-- for date: SYSDATE
-- for sql command: v_trg_action
END trg_audit_books;


This is all you need to use audit trail.
Special thanks to Roel and Anthony who helped me out a bit: http://forums.oracle.com/forums/message.jspa?messageID=3240814
APEX-AT-WORK no image

Using individual error/success messages in APEX

Von Tobias Arnhold → 1.25.2009
There are several ways about how to use own error/success messages in APEX page processes. I want to show how to use the internal APEX process.

To create an own alert message in a page process use that syntax:

apex_application.g_print_success_message := '<span style="color:green">Data from ' || :P1_DATE || ' successfully updated</span>';

With that function you replace the text of the internal APEX Process Success Message.

PL/SQL process example with own dynamic messages:

begin
IF :P1_COMPUTER like 'PC%' THEN
INSERT INTO...;
COMMIT;
apex_application.g_print_success_message := '<span style="color:green">Computer created</span>';
ELSE
apex_application.g_print_success_message := '<span style="color:red">No valid computer name</span>';
END IF;
END;

Example with own alert messages for updateable reports in a page process:
(In this example we have an updateable report with time values like 'hh24:mi' = '06:30'. Every object needs to be checked via a function check_time before an update will be made. If the result is 0 then a error message should occur)

DECLARE
-- variables
v_error number;
BEGIN

FOR i IN 1 .. APEX_APPLICATION.g_f50.COUNT -- count number of rows in this report
LOOP
-- UPDATE procedure
CASE WHEN check_time(APEX_APPLICATION.g_f01(i)) = 0 THEN
apex_application.g_print_success_message := '<span style="color:red">Value ' || APEX_APPLICATION.g_f01(i) || ' is wrong.</span>';
ROLLBACK;
v_error := 1; EXIT;
ELSE
-- now an update command could be set
null;
END IF;
CASE WHEN check_time(APEX_APPLICATION.g_f02(i)) = 0 THEN
apex_application.g_print_success_message := '<span style="color:red">Value ' || APEX_APPLICATION.g_f02(i) || ' is wrong.</span>';
ROLLBACK;
v_error := 1; EXIT;
ELSE
-- now an update command could be set
null;
END IF;
CASE WHEN check_time(APEX_APPLICATION.g_f03(i)) = 0 THEN
apex_application.g_print_success_message := '<span style="color:red">Value ' || APEX_APPLICATION.g_f03(i) || ' is wrong.</span>';
ROLLBACK;
v_error := 1; EXIT;
ELSE
-- now an update command could be set
null;
END IF;
-- CASE ...
-- depending on the amount of columns
END CASE;
END LOOP;
-- no commit if error occurred, error only occur when validation went wrong
IF v_error is null then
COMMIT;
apex_application.g_print_success_message := '<span style="color:green">Updates successfully applied</span>';
END IF;
END;


That updateable process should just show how particular you can use these error/success messages in your application. With some javascript you could also change the object which is wrong. For example with a red object background.

Here are some posts to that topic in the Oracle forum:
http://forums.oracle.com/forums/thread.jspa?messageID=2717151
http://forums.oracle.com/forums/thread.jspa?messageID=2792051

Multiple APEX regions in the same size (width)

Von Tobias Arnhold → 1.12.2009
First of all (I know its a bit late) I wish everybody a healthy and successfully year 2009.
Now let's talk about APEX...

Have you every came about the problem that you have several reports on a page and they all show up in a different size. Most annoying is the different sizes of the width.

What you can do to bring them all into the same width is to edit the template region or to copy it to a new one and change some html attributes. Unfortunately every theme has there own unique source code. So you need to find out the right settings yourself. In my example I used the theme Centered - 7 and changed the following definition line under Home > Application Builder >Application #ID# > Shared Components > Edit Region Template > Defintion:

<td align="center" colspan="2">#BODY#</td>

To:

<td align="center" colspan="2" #REGION_ATTRIBUTES#>#BODY#</td>


Next is to edit your regions. Add style="width:600px" at the region attributes.

Here an example: http://apex.oracle.com/pls/otn/f?p=25472:29

Just a tip:
To find out where you need to add the attribute #REGION_ATTRIBUTES# use Firefox with Firebug.