Another 5 neat 12c features for Oracle developers

In this post I will put 5 other new 12c features in the spotlight (in addition to the features of a previous post), that really makes the 12c an improvement against the previous versions of the Oracle database.

To get this result I listed up all the major new features and wanted to know my top 5 features that would make my life easier(as a developer), excluding the features from the previous  post (I certainly would have added the sequence modification(feature 1)), when doing development on an Oracle database.

  1. Top end query -> I really like this feature and I’m still wondering why it took Oracle so long before creating it. It is something I could have used a lot in the past, but instead I had to create far too complicated, not as nice readable queries to achieve this. How does it work? Well it’s very easy and it’s readable and can be used in a wide variety of cases. Some examples:
    Only get the first 3 rows:
    select * from X order by id
    fetch first 3 rows only;

    Skip the first 3 rows and get the next 3 rows:

    select * from X order by id
    offset 3 rows fetch next 3 rows only;

    Get the first 50% of records

    select * from X order by id
    fetch first 50 percent rows only;

    Get the first 3 rows together with the records equal to these department id’s

    select * from emp order by deptno
    fetch first 3 rows with ties;

    If you want the capture the last rows, you can obviously change ‘first’ with ‘last’…

  2. In the 12c database the use of 32767 characters for a VARCHAR2 in SQL is now available instead of the maximum of 4000(this is also the case for RAW and nvarchar2).
    We all have been waiting a long time for this one and before we had to use the clob datatype.
    But beware this is not an out of the box feature, you will have to execute the lines below before this is enabled :
    shutdown immediate
    startup upgrade
    alter system set max_string_size=EXTENDED scope=both;
    @<ORACLE_HOME>/rdbms/admin/utl32k.sql
    Shutdown immediate
    Startup

    More info can be found on: http://docs.oracle.com/cd/E16655_01/server.121/e17615/refrn10321.htm

  3. The invisible column is a feature of which I was wondering where I could use it for.
    Well it could be handy when you are adding a column to your table, but you don’t want any existing code to be impacted by it.
    Another case where it could be useful, is when using audit columns.  Columns as the creation_dt, update_dt, user_creation and user_update will only be of any added value when you would like to audit a certain column.
    Packages with inserts, updates, references to this table will not be impacted by the creation of this column.
    On the other hand there is also a risk that you forget that this column is in there, because you have to explicitly call for it (a describe or select * will not show this column). You can create invisible columns like this:

    ALTER TABLE
    ADD  INVISIBLE;

    If you want to make the column visible again, use this:

    ALTER TABLE
    MODIFY VISIBLE;

    In summary it could be handy, but don’t forget this column or it will pollute your table.

  4.  The with clause inline plsql feature is also something that I think is very welcome.
    It will make it possible to create a procedure or function inside your select statement instead of having to create this in a package or function. Oracle also says that this will optimize the performance against having to call a schema procedure/function(I still have to test this).
    A little example:

    WITH
    FUNCTION fnc$_add_one(p_num IN NUMBER) IS
    BEGIN
    RETURN p_num+1;
    END;
    SELECT fnc$_add_one(1)
    FROM DUAL;
  5.  Most of the time I use the ANSI way of writing for a left outer join, but the oracle way of writing left outer joins is still often used by many of the oracle developers.
    But there was one thing that you could do in ANSI, that you couldn’t in the oracle way.  You couldn’t write multiple tables on the left of an outer join, untill12c…
    In 11g and before when coding something like this:
    select *
    from a,b,c
    where a.id = b.id
    and a.id = c.id(+)
    and b.id = c.id2(+);

    This resulted in -> ORA-01417: a table may be outer joined to at most one other table

    In 12c this will work, also the ANSI solution obviously still works both on 12c and on 11g

    select *
    from a
    JOIN b ON (a.id = b.id)
    LEFT OUTER JOIN c ON (a.id = c.id AND b.id = c.id2);

Together with the previous post this makes 10 reasons why you should start to use the Oracle 12c database :-)

Oracle DB 12c, APEX 5.0 and APEX tech sessions at OGH APEX World

April 9th 2013, APEX World took place, one of the biggest APEX only events in the world, organized by the Dutch Oracle user group (OGH). iAdvise was gold partner of this year’s edition. Below is a view on this event from our perspective.

iAdvise stand

iAdvise booth

The event took flight with the keynote by David Peake, product manager from Oracle. He spoke about Oracle DB 12c, what it is and what’s in there for APEX developers, and some words about what to expect from APEX 5.0. Again, we had to conclude that great things are coming our way in the months to come:

  • pluggable databases,
  • new column types,
  • data redaction,
  • new IDE-like view for the page builder,
  • multiple interactive reports on 1 page,
  • multi-row edit region type,
  • enhanced builder security
  • and some more great stuff…

But as we are used to with Oracle, it’s all subject to change and might not make it into next release :-)
More in-depth details and another view on this presentation can be found on Christian Rokitta’s blog.

The only two things David was clear about were:

  • APEX 5.0 will focus on improved usability and quality rather than on new features;
  • there will be an APEX 4.2.2 release before 5.0 will become available.

Below are our highlights from the presentations we followed.

Transfer Solutions presented their “portal” solution to combine both Forms and APEX applications with one custom single sign-on. We saw some interesting approaches for common issues and found confirmation for our approach in comparable situations.

Rob van Wijk from Ciber presented his white paper “Professional software development using APEX”. Together with his colleagues, he worked out a way to version database schemes and APEX applications in Subversion when all developers are working in their own isolated environment. On top of this, he used Hudson to automate the versioning update-commit process. A must read paper if you consider versioning within your APEX environment!

Regarding responsive web design (RWD), there were two presentations of interest:

Dimitri Gielis introduced how RWD can be accomplished in APEX by using the new built-in grid system and spoke about APEX theme 25 (fully responsive and new in APEX 4.2) but also Twitter bootstrap, which can perfectly be integrated in APEX.

Later on, it was up to CB Logistics, together with iAdvise colleague Stijn Van Raes, to present how they used RWD in a recent project.

Peter Raganitsch and Matt Nolan from FOEX came all the way to Zeist to state that APEX truly is the best successor of Oracle Forms…but not out-of-the-box. In a few demos, in which they combined declarative APEX functionality together with their plug-in framework, they showed how APEX can become a perfect fit for everyone who wants to migrate good old Forms without losing much functionality, usability and maintainability. A bold statement but definitely something our APEX developers will look into.

Roel Hartman showed us what mobile web development with APEX theme 50 and jQuery mobile is all about. He walked through the new item types, lists and buttons and demonstrated how you can easily make your application look better with standard APEX functionality.

Our iAdvise colleague, Karen Van Hellemont, presented with Natasha Van Hoof from the Flemish Government how documents can be generated from the database. Throughout several years, iAdvise gained experience in generating documents with PL/SQL and developed a metadata driven solution with a simple API to re-use it in other projects. The Flemish Government is our first customer to use the complete version of this solution and therefore gave a customer testimonial on their experience with the tool.

The price for most-entertaining presentation definitely goes to John Scott (APEX Evangelists) when talking about HTML5 websockets! The concept of websockets took about 10 minutes. The remaining time was used for demos about what you can do with this. We never heard so many sounds of astonishment in 30 minutes!

For a Belgian-Dutch Oracle consultancy company, this is one of the most valuable events next to Oracle Open World and this year’s edition really showed us that APEX is far from ever going away! It has great potential for a very wide range of businesses and allows both developers and end-users to maximize their needs in every way.

Using a database link with heterogeneous services in APEX

Last weeks I ran into some issues with APEX, so let’s take some time to write something about them.

The most recent is about heterogeneous services (also referenced as HS). Here is the case:
We have an Oracle DB instance with some APEX applications and in one of those applications I need data from a MS SQL server database. Not a very good idea, but the set-up couldn’t be changed and both databases can handle it, so I gave it a try.

Our DBA installed heterogeneous services and created a database link between the two databases. Querying the necessary views was pretty easy (I only needed a couple of synonyms for ease of maintenance) and data came in faster than expected.

The next step was to query these views with APEX.
Because I created Oracle views on the views of MS SQL server, this was also very straightforward for APEX.

After a while however, there were issues in other applications and also the APEX builder itself raised errors while uploading files and importing applications. The following error returned:

ORA-02047: cannot join the distributed transaction in progress

, usually accompanied by some other ORA error codes. Not a very descriptive error message. A colleague pointed out to me that it has something to do with database links and heterogeneous services.

So, what is the problem?
APEX starts a new database session for my application. In this session the database link to the MS SQL server database is opened and data is queried. Since APEX constantly changes and re‑uses database sessions (this technique is called session pooling), the database session is released after a while and put back in the session pool until another application needs a new/another session. Because the database link in my session is only used for querying, there is no line of code that closes the database link so it remains open, even when the session is put back into the session pool. When another application takes this session from the pool, there might be issues with specific transactions, like setting a context (e.g. setting NLS parameters), because Oracle wants to perform this operation on both the Oracle database and the linked MS SQL server database. Because an NLS parameter is set when uploading a file, the end user receives the ORA-02047 error.

What can one do to prevent this from happening? There are several solutions for this issue:

  1. Don’t use database links with heterogeneous services. This is the easiest solution but isn’t always possible.
  2. Only access data over a DB link with HS in a package, function, procedure,… and close the DB link at the end of your block of code, which is not always possible either.
  3. Close any open database link, or only the specific one, when you put your session back into the session pool.

For the third solution, something interesting is implemented in APEX 4.1.

At application level, you can define some PL/SQL code that should be executed when initializing or returning a session from/to the session pool.

You can find this section under Shared Components  >  Security Attributes. All the way at the bottom is the section ‘Database Session’:

In earlier versions of APEX, something similar was already available for VPD (Virtual Private Database) but this only allowed execution of code at session initialization. The APEX development team has now expanded this functionality for any PL/SQL in general, so not only VPD-related, and both at session initialization and returning.

For my issue, all I had to do was write some code to close the database link when it was still open. I created a function in my application database schema which returns the number of open database links with a specified name:

CREATE FUNCTION is_dblink_open(dblink  IN VARCHAR2)
RETURN INT
AS
  l_cnt   INT;
BEGIN
  SELECT COUNT(db_link) INTO l_cnt
  FROM v$dblink
  WHERE db_link = dblink;
  RETURN l_cnt;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    RETURN 0;
END;

Before you create this function, don’t forget to grant access to v$dblink:

GRANT select ON v_$dblink TO my_app_schema;

Execute with SYS. Note the v_$ instead of v$! (more info: http://goo.gl/euxcs).

All that was left is to use this function in the Database Session Clean Up Code:

DECLARE
  l_dblink VARCHAR2(100) := 'MY_SQL_SRV_DBLINK';
BEGIN
  IF is_dblink_open(l_dblink) > 0 THEN
    DBMS_SESSION.close_database_link(l_dblink);
  END IF;
END;

Or if you want to be sure that all open database links are closed, you could use:

BEGIN
  FOR l_db_link IN ( SELECT db_link AS name FROM v$dblink ) LOOP
    DBMS_SESSION.close_database_link(l_db_link.name);
  END LOOP;
END;

Special thanks to my colleague Jan for pointing out to the HS problem and to Patrick Wolf for helping me on this issue through the Oracle APEX forum (read the full post here: http://goo.gl/vVoeb).

This way, I hope to help out other people too when they run into this issue.

Oracle Forms 11g and Apex using external events

I remembered an old post of Roel Hartman where he integrated a form into apex.
He used a part of OraFormsFaces by Wilfred van der Deijl: the CommunicatorBean.
Using this CommunicatorBean forms could react on “external messages”.
Now with Forms 11g reacting on external events, this CommunicatorBean isn’t necessary any more(sorry Wilfred).

This is how I did it using external events…
First things first: set up the advanced queueing mechanism.
Check this tutorial which includes setting up advanced queueing.
I created a little form based on emp(nothing fancy)…

The new feature in forms:

With the following properties:

What should forms execute when this event happens?
This has to be specified in the When-event-raised trigger.

In this case we retrieve the payload and extract the empno from it.
The empno is used to set the default where clause on the block.
When there’s an empno on the queue, forms will query that employee.
That’s all for the forms part…
Now I created a little Apex page with two regions:

The Employee details will be our form.
So I put our form in the HTML using an iframe:

Using a “select list” it’s possible to select an employee.

This is the result:

Now the purpose of the select list is to choose an employee and show the detail information in our form.
In order to do this, the select list calls a javascript function.

This javascript function is created in the HTML header

The code behind this:

<script language=”JavaScript” type=”text/javascript”>
function getEmployee (){
var emp = $x(‘P2_EMPNO’);
// send request
var ajaxRequest = new
htmldb_Get(null,&APP_ID.,’APPLICATION_PROCESS=get_emp’,0);
ajaxRequest.add(‘P2_EMPNO’,emp.value);

// get response
ajaxResult = ajaxRequest.get();
ajaxRequest = null;
}
</script>

This javascript function calls an application process and uses the empno as parameter.
The application process put the empno on the queue.

When changing the select list, the form is queried

This is a solution to integrate forms into another application whether it’s Apex, ADF or another web applicaton.
When it can put something on the queue, forms can react on it.
And yes, I could do it using the javascript feature in Forms 11g. I know…
And for Apex it’s probably a better solution, as we can skip the AQ part and make calls to and from forms in Javascript.