Browsing "Older Posts"

AaW - DBMON First pictures / Erste Bilder

Von Tobias Arnhold → 2.22.2010
The following post is targeted towards a German audience, thus it is in German:

Anfang Februar habe ich über eine Oracle DB Monitoring Anwendung für die deutsche APEX Community berichtet: Whats about the German APEX users?
Endlich habe ich es geschafft ein paar Screenshots zu erstellen. Die Anwendung basiert auf APEX und ExtJS und sammelt derzeit folgende Informationen:
- Tablespace Auslastung
- CPU Auslastung
- Buffer Hitratio Auslastung
- Session Zähler
- PGA Auslastung
- Init.ora Paramter
- Aktueller DB Status

Daten werden durch den DBMS_SCHEDULER über ein PL/SQL Package zu spezifizierten Zeiten gesammelt und können dadurch rückwirkend ausgewertet werden.
Gerade für Oracle XE Umgebungen kann dieses kleine Tool von nutzen sein.

Derzeit suche ich noch Beta-Tester, um für Ende März eine erste Testversion auf Herz und Nieren zu überprüfen. Wenn Interesse besteht, schickt einfach eine Email an: Tobias Arnhold (tobias-arnhold@hotmail.de)

Hier die ersten Screenshots:



APEX-AT-WORK no image

Set item value with AJAX

Von Tobias Arnhold → 2.17.2010
Update an APEX item dynamically with AJAX:

// 1. Item: HTML Form Element Attributes:
onChange="javascript:fnc_setValue('P1_VALUE')";

// 2. Page: HTML Header
<script language="JavaScript1.1" type="text/javascript">
function fnc_setValue(v_item)
{
var get = new htmldb_Get(null,&APP_ID.,'APPLICATION_PROCESS=v_dummy',0);
get.add(v_item,html_GetElement(v_item).value)
gReturn = get.get();
html_GetElement(v_item).value = v_item;
get = null;
}
</script>

Denes described it more detailed (plus example) in his blog:
Setting Item Session State using Ajax

Have you seen the advanced freeze panes example like you can use in Oracle Forms?
Freeze Panes in an APEX Report: Now with columns

Updated script 22.02.2010:

// 1. Item: HTML Form Element Attributes:
onChange="javascript:fnc_setValue('P1_VALUE')";

// 2. Page: HTML Header
<script type="text/javascript">
function fnc_setValue(v_item)
{ // Works with select lists, radio buttons, ...
var get = new htmldb_Get(null,&APP_ID.,'APPLICATION_PROCESS=v_dummy',0);
get.add(v_item,$v(v_item))
// For Display as Text items add:
// html_GetElement('v_item').innerHTML = $v(v_item);
gReturn = get.get();
get = null;
}
</script>
APEX-AT-WORK no image

Making a connection from Oracle XE to MySQL with ODBC

Von Tobias Arnhold → 2.15.2010
After searching the Web I found a nice description from James Koopmann: Making a Connection from Oracle to SQL Server

Then I found a Metalink note: WIN NT - Generic Connectivity using ODBC [ID 114820.1]

What software do you need? MySQL ODBC driver

Now follow these steps:
1. Add a new file:
<ORACLE HOME>\hs\admin\initMYSQL_DB.ora
# This is a sample agent init file that contains the HS parameters that are
# needed for an ODBC Agent.

#
# HS init parameters
#
HS_FDS_CONNECT_INFO = MYSQL_DB
HS_FDS_TRACE_LEVEL = OFF

#
# Environment variables required for the non-Oracle system
#
#set =


2. Update your Listener.ora (In my case I use the existing one):
...
(SID_DESC=
(SID_NAME=MYSQL_DB)
(ORACLE_HOME=F:\oracle\app\oracle\product\10.2.0\server)
(PROGRAM=hsodbc)
)
...

3. Update your TNSNAMES.ora and restart your Listener:
...
MYSQL_DB =
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.1)(PORT=1521))
(CONNECT_DATA=(SID=MYSQL_DB))
(HS=OK)
)
...

4. Create database link inside your database:
create database link MYSQL_DB
connect to "test_db" identified by "test_db"
using 'MYSQL_DB';

5. SQL> select * from test_table@MYSQL_DB;

Issues I know about: Invalid identifier problem

AJAX based select list in APEX

Von Tobias Arnhold → 2.08.2010
I looked through the Web for a simple way using a select list with dynamic data exchange inside my APEX application. What I found was just amazing (Thanks to Scott):

ajax-select-list-code-generator for APEX

Select list code generator

Output:

MySQL/Oracle XE integration: Invalid identifier problem

Von Tobias Arnhold →
I linked a MySQL table into an OracleXE database (Short How to) and discovered a really strange behavior. When I tried an usual select about the MySQL table from my sqlplus client an error occurred: ORA-00904: "last_name": Invalid identifier

Here the whole description:

-- Error:
Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
Connected as test_user

SQL> SELECT "last_name" FROM tbl_users@MYSQL_USER u;

SELECT "last_name" FROM tbl_users@MYSQL_USER u

ORA-00904: "last_name": ungültiger Bezeichner

SQL>

-- MySQL DDL TABLE:
DROP TABLE IF EXISTS 'my_sqldb'.'tbl_users';
CREATE TABLE 'my_sqldb'.'tbl_users' (
'u_id' int(10) unsigned NOT NULL auto_increment,
'last_name' varchar(50) NOT NULL,
'forename' varchar(50) NOT NULL,
'department_id' int(10) unsigned NOT NULL,
PRIMARY KEY ('u_id')
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;

Solution:
Query MySQL table through Oracle APEX database using Oracle database link fails
Issue while querying MySQL tables through Oracle Generic Connectivity Using ODBC

Solution description:

...I changed the character set settings to "utf8" of v5.1.6 mysql odbc driver
through "Details -> Misc Options" as suggested and finally the problem was
resolved - the query returned the correct results...

APEX-AT-WORK no image

Creating an ExtJS tree with PL/JSON

Von Tobias Arnhold → 2.04.2010
I searched for a smoother way building ExtJS trees in APEX and found a great post from Anja Hildebrandt: Nice trees with ExtJS (Erstellung eines ExtJS-Baums…)

She used the PL/JSON Utility from Lewis Cunningham: PL/JSON by jkrogsboell, lewiscunningham

During the time now Lewis developed a new version of the utility and Anjas code didn't work anymore. I updated her source code with the new version of PL/JSON 0.8.6.

First I show how you build JSON output with the PL/JSON scripts:
Example - ex4.sql

SQL> declare
2 obj json;
3 procedure p(v varchar2) as begin dbms_output.put_line(null);dbms_output.put_line(v); end;
4 begin
5 p('you can also put json or json_lists as values:');
6 obj := json(); --fresh json;
7 obj.put('text', 'Audi');
8 obj.put('id', 100);
9 obj.put('leaf', json_bool(true));
10 obj.put('href', 'f?p=110:1:');
11 obj.put('children', json_list('[{"text": "A4"},{"text": "A5"}]'));
12 obj.print;
13 end;
14 /


you can also put json or json_lists as values:
{
"text" : "Audi",
"id" : 100,
"leaf" : true,
"href" : "f?p=305:1:",
"children" : [{
"text" : "A4"
}, {
"text" : "A5"
}]
}

PL/SQL procedure successfully completed

PL/JSON forum example
 
SQL>
SQL> DECLARE
2 resultset json;
3 row_list json_list := json_list();
4 columns1 json;
5 num_rows number := 2;
6 columns_length number := 3;
7 procedure p(v varchar2) as begin dbms_output.put_line(null);dbms_output.put_line(v); end;
8 BEGIN
9 p('Data:');
10 FOR i IN 1 .. num_rows
11 LOOP
12 columns1 := json();
13 columns1.put('rownum', i);
14 FOR x IN 1 .. columns_length
15 LOOP
16 columns1.put('column' || x, 'Testdata');
17 END LOOP;
18 row_list.add_elem(columns1.to_anydata);
19 END LOOP;
20 resultset := json();
21 resultset.put('ResultSet', row_list);
22 resultset.print;
23 END;
24 /


Data:
{
"ResultSet" : [{
"rownum" : 1,
"column1" : "Testdata",
"column2" : "Testdata",
"column3" : "Testdata"
}, {
"rownum" : 2,
"column1" : "Testdata",
"column2" : "Testdata",
"column3" : "Testdata"
}]
}

PL/SQL procedure successfully completed

SQL>

Updated tree package of Anja

create or replace package PKG_EXTJS_JSON is

-- Author : AHILDEBRANDT
-- : TARNHOLD
-- Created : 10.08.2009
-- Updated : 04.02.2010
-- Purpose : check if category has sub-categories
function hasChildren(i_cat_id in number) return boolean;

-- Purpose : create JSON-Object for category;
-- recursive
function getJsonObject(i_cat_id in number default 0) return json;

-- Purpose : function that calls getJsonObject and returns the result as string
function getTreeDataDynamic return varchar2;

end PKG_EXTJS_JSON;

create or replace package body PKG_EXTJS_JSON is
/*
-- Author : AHILDEBRANDT
-- : TARNHOLD
-- Created : 10.08.2009
-- Updated : 04.02.2010
-- Purpose : check if category has sub-categories
*/
function hasChildren(i_cat_id in number) return boolean is
v_count number:=0;
begin
select nvl(count(*),0) into v_count from tbl_categories where c_par_id=i_cat_id and c_active = 'YES';
if v_count>0 then
return true;
else
return false;
end if;
end;

/*
-- Author : AHILDEBRANDT
-- : TARNHOLD
-- Created : 10.08.2009
-- Updated : 04.02.2010
-- Created : 10.08.2009
-- Purpose : create JSON-Object for category;
-- recursive
*/
function getJsonObject(i_cat_id in number default 0) return json is
v_json json:=json();
v_row_list json_list := json_list();
v_arr_id NUMBER;
v_ele_id NUMBER;
begin

if i_cat_id = 1 then -- if category is root then set root-node
v_json.put(pair_name => 'id', pair_value => i_cat_id);
v_json.put(pair_name => 'text', pair_value => 'Root');
else -- else --> usual node; use category infos
for cat in (select * from tbl_categories where c_id=i_cat_id and c_active = 'YES') loop
v_json.put(pair_name => 'id', pair_value => i_cat_id);
v_json.put(pair_name => 'text', pair_value => cat.c_name);
end loop;
end if;

if not hasChildren(i_cat_id) then -- if node has no children
v_json.put(pair_name => 'leaf', pair_value => json_bool(true)); -- mark as leaf
v_json.put(pair_name => 'href', pair_value => 'f?p=110:1:'||v('APP_SESSION')); -- set a link if needed
-- v_json.put(pair_name => 'href', pair_value => 'javascript:show_cat('||i_cat_id|| ');'); -- set a javascript function
else -- sonst
v_json.put(pair_name => 'leaf', pair_value => json_bool(false)); -- mark as node with children
for child in (select * from tbl_categories where c_par_id=i_cat_id and c_active = 'YES') loop -- loop through all sub-categories
-- create JSON-object for sub-category using recursive call and the append to array
v_row_list.add_elem(getJsonObject(i_cat_id => child.c_id).to_anydata);
end loop;
v_json.put(pair_name => 'children', pair_value => v_row_list); -- add array for subcategories
end if;

return v_json;

end;

/*
-- Author : AHILDEBRANDT
-- : TARNHOLD
-- Created : 10.08.2009
-- Updated : 04.02.2010
-- Purpose : function that calls getJsonObject and returns the result as string
*/
function getTreeDataDynamic return varchar2 is
v_json json:=json();
begin
v_json:=getJsonObject(i_cat_id => 1);
return('['||v_json.to_char||']');
end;

end PKG_EXTJS_JSON;

Utilities like this makes developing much more faster!
APEX-AT-WORK no image

Whats about the German APEX users?

Von Tobias Arnhold → 2.01.2010
Why German? I come from and live in Germany! ;D
I haven't really provided lot's of APEX based information in German. This just has to change. What to do?
Last year I created a small Oracle monitoring application with APEX and ExtJS. It was developed to collect CPU, Tablespace, Init.ora, Session and even more information about Oracle databases. In combination with some other monitoring tools it was quite a good (cheap) alternative to some expensive tools.

More details soon (in German)...
APEX-AT-WORK no image

Send HTML data with the POST method from APEX

Von Tobias Arnhold →
If you want to send data from your APEX application to an external website (like PHP) through the POST method. You can use the following example:

Add a new page (in my example it's page number 2)


Add a new button on the page where you want to send data from: BTN_SEND_DATE
With the following options:
Target is a: URL
URL Target: javascript:void(window.open('f?p=&APP_ID.:2:&SESSION.:::::', 'popup', 'toolbar=no,width=1024,height=768, resizable=yes,top=40,scrollbars=yes'));

On page 2: Add your variables

1 P2_ID Hidden -- Needs to be set before page load
2 T_NAME Hidden
3 T_DESC Hidden
3 T_USER Hidden
....

Set variable P2_ID before you open page 2


On page 2: Page Process - Before Header

BEGIN
IF :P2_ID IS NULL THEN
:T_NAME:= 'Error - No data selected';
:T_DESC := 'Error - No data selected';
:T_USER := 'Error - No data selected';
ELSE
-- Select data
SELECT t.t_name,
t.t_description,
initcap(:P1_USERNAME)
INTO :T_NAME,
:T_DESC,
:T_USER
FROM test_table r
WHERE t.t_id = :P2_ID;
END IF;
END;

On page 2: Page - Footer Text

<script>
html_GetElement('T_NAME').name = 'T_NAME';
html_GetElement('T_NAME').value= document.getElementById('T_NAME').value;
html_GetElement('T_DESC').name = 'T_DESC';
html_GetElement('T_DESC').value= document.getElementById('T_DESC').value;
html_GetElement('T_USER').name = 'T_USER';
html_GetElement('T_USER').value= document.getElementById('T_USER').value;

html_GetElement('wwvFlowForm').action='http://website/external.php';
html_GetElement('wwvFlowForm').method='post';
html_GetElement('wwvFlowForm').submit();
</script>

Forum entries which helped me a lot:
Thread: item name isn't what i specified
Thread: HTTP POST from APEX
Thread: HTML form in Apex page

Example page:
Jeff Eberhard's application

Thanks Jeff for your example and your posts about this topic!