Thursday, May 31, 2012

DG Tournament open for Euro 2012

Just a quick note to say I entered the matches of UEFA Euro 2012 in DG Tournament now, so you can bet on the games again (don't forget to add this tournament to Your Profile first after you login).

A new banner is on his way... To be honest, I didn't think of opening it up again for this tournament as Belgium isn't qualified, but obviously other countries did qualify ;-) and it sounds people looked forward to play again (looking at the messages I received).
And yes, I must admit, even when your own country doesn't play, it's more fun to predict a score with friends first and than watch the game.

Time goes so fast... It's already 6 years ago I created the initial site to bet on the WorldCup 2006!
If you want to read some more history on DG Tournament you can do that here. I didn't do any updates to the app this year. I did think of putting this app on the Oracle Public Cloud or make a mobile version of it to showcase the power of APEX 4.2 (and JQuery Mobile), but as those didn't go live yet, and I currently don't have that much spare time, I decided against it.

I didn't really foresee prices like I did before... it's all about honour this time!

If you are using Oracle Application Express, and you are in the top 3 ranked people, I'm happy to give away an Export Oracle Application Express books.

That the best may win!

Wednesday, April 11, 2012

Oracle APEX Plug-ins Competition

You have some Oracle Application Express (APEX) plug-ins written but didn't share them yet? or you plan on writing some new APEX plug-ins? Why not submit them to the APEX Plug-ins competition?!

You not only get the recognition of being an APEX plug-in developer, but you can actually win some prices too... and maybe even better, be the first 2012 ODTUG APEX Plug-in Developer of the year!

You find all the information and rules on the APEX plug-in competition page.

To get started on creating plug-ins it's always useful to look at existing plug-ins and steal with your eyes...

I look forward seeing your plug-in! Happy coding...

Monday, March 26, 2012

APEXBlogs reloaded

Since March 7th APEXBlogs.info didn't pick up new blog posts anymore.

Thanks for everybody mailing me, telling me or sending me feedback about the issue. It's nice that many people "missed" APEXBlogs... I'm sorry it took me some long to look into the issue.

Today I found some time to look a bit closed into the issue. Apparently in one of the blog posts somebody put a very strange character in. To fix my procedure I had to include following code:


So basically I replace that strange character with a space and everything worked again normally...

Over 20 new posts are included now in APEXBlogs, so happy reading again!

Wednesday, February 22, 2012

Apply APEX 4.1.1 Patch Set

Yesterday APEX 4.1.1 Patch set was made public. If you already have APEX 4.1 installed you can download patch number 13331096 from My Oracle Support.

If you are on a previous version of APEX you can download the complete install of APEX 4.1.1 from OTN.

I installed the patch today on my APEX 4.1 instances and it installed without a problem. It took not more than 5 minutes to complete the entire patch.


Two things to look for when you copy the images folder
- for Apache on Linux I used this command:
cp -rf patch/images /u01/ohs/apex/ (so without images folder)
- for the APEX Listener I used this command:
cp -rf patch/images/* /u01/app/glassfish3/glassfish/domain1/docroot/i (so without images folder)

When I first did the copy it included another images folder. If you go to your images folder and go into the themes folder you should find the new theme 24 folder. If you find it, than everything is copied ok.


Which brings me to; there is a new theme in APEX 4.1.1. Theme 24, the "cloudy" theme! This theme looks very nice and more 2012 (bigger fonts etc).
It would be great if Oracle would setup an official theme repository, like they did for plugins. Designing nice looking sites takes time and the web design "trends" change fast.


There was one other catch after applying the patch; some workspaces weren't accessible anymore. I got this error:

--
Workspace "" is inactive. Contact your administrator.
Contact your application administrator.
--

This was due to the way I created some of those workspaces in APEX 4.1.
Instead of going through the wizard I used the API to create the workspace:

apex_instance_admin.add_workspace(
  p_workspace_id       => v_workspace_id,
  p_workspace          => v_workspace,
  p_primary_schema     => v_primary_schema,
  p_additional_schemas => v_additional_schemas);

This worked fine before, but after applying the patch if you didn't run:

apex_instance_admin.enable_workspace('');

It doesn't work. Thanks to the APEX development team to diagnose the cause so quickly and come up with the solution. Patrick Wolf posted a script to fix any workspaces you may have with that issue.

Also don't forget to read about some possible changes of behaviour (depending compatibility setting) in the patch notes:
  • Changes in Page and Region Caching
  • Columns Used in Automatic Row Processing (DML) Processes
I definitely think it's good to apply this patch. I already applied some one off patches before for the urgent issues I was facing, but having this patch set brings you immediately to the latest and greatest!

Tuesday, February 14, 2012

Overview APEX -> EBS, next EBS -> APEX

In the previous posts I mainly focussed on getting information out of E-Business Suite and use it in my APEX application. This is especially useful for people using APEX.

Visually I see it like this:


Here is a complete overview of those posts:


  • Calling EBS Webservices from APEX
  • Using EBS Open Interface from APEX
  • Debugging EBS API calls in APEX
  • Updating EBS data from APEX using Triggers and APIs (3)
  • Creating EBS data from APEX using APIs (2)
  • Updating EBS data from APEX using APIs (1)
  • Querying EBS data from APEX using Views
  • E-Business Suite and APEX integration (overview)
  • E-Business Suite and APEX installation


  • I can imagine that people coming from the E-Business Suite are not that interested in creating stand-alone APEX applications, but they are more into creating an APEX page to extend EBS. They want to be in EBS, and in the menu some links will just open up some APEX pages. They want to see the information that is relevant at that time and have a seamless integration (so no extra logins etc).

    I visualise that flow like this:


    We can obviously use many of the techniques described in the other posts, but how does the authentication, authorisation etc work? Most of that is described in the Oracle white paper with a good example (starting at page 11). I might do some extra blog posts about that integration, but it will be in line with the white paper.

    Calling EBS Webservices from APEX

    Another way to integrate with E-Business Suite from APEX is through Webservices.
    You could setup a complete BPEL and SOA environment or you can do it a bit simpler.

    First you start by going to the EBS Integration Repository. I found it useful to view by Interface Type as then I could select XML Gateway Map.


    For the different products inside EBS you find the different gateways. Most of them have a WSDL.
    I won't give a complete run through demo as I'm currently working with HR and I didn't see an XML Gateway for that. Nevertheless I will tell you how I would do it.

    In APEX go to Shared Components > Logic > Web Service References.

    Create a new Webservice based on a WSDL (the one you selected from the EBS Integration Repository)


    And follow the wizard from there. You don't need to search the UDDI, you can just copy the WSDL location. Once the wizard is finished I tend to create a new page (form and report) based on this Webservice so I don't need to create the possible parameters/items manually etc.


    Finally I customise the page to fit my needs. That should be it... (in theory)

    Using EBS Open Interface from APEX

    I decided against integrating E-Business Suite Open Interface into my APEX application as I didn't really need it at the moment.

    Nevertheless I want to quickly give my view on it. Open Interface tables (OIT) seems to be the common use to do interfacing with EBS. It looks especially interesting when you have to load a lot of records into EBS. Open Interfaces do a lot more than the API calls, in fact they may do multiple API calls at once and they keep error records too. Many products in EBS have a number of OIT available.

    If you google for Open Interface table (or just open interface ebs) you find a lot more info than I'm giving here.

    More info I found useful:

    Monday, February 13, 2012

    Debugging EBS API calls in APEX

    This picture comes from Dmitry Vostokov site.
    While I was looking into E-Business Suite and especially the API calls, I wondered how I could debug what was going.

    I find it important to understand what I'm doing. EBS is big, but the more I get into it, the more I want to know what is going on (because the more I get into having issues ;-)).

    Although I don't have the time right now to really dive into a detailed EBS-APEX debugging post, I quickly want to share my ideas.

    In EBS people tend to use the hr_utility package to trace what is going on. You can do something like :

    apps.hr_utility.set_trace_options ('TRACE_DEST:DBMS_OUTPUT');

    Unfortunately if you don't have SQL Plus or SQL Developer access to the EBS database and you only have APEX, what do you do? It would be nice if the TRACE_DEST parameter would allow HTP as a value, but it doesn't.

    So here is some pseudo-code I thought would help me to debug from within my APEX app (or SQL Workshop):


    BEGIN
      if APEX_APPLICATION.G_DEBUG
      then
        -- trace_dest possible values: DBMS_PIPE, DBMS_OUTPUT, PAY_LOG
        apps.hr_utility.set_trace_options ('TRACE_DEST:DBMS_PIPE');
        -- set trace on
        apps.hr_utility.trace_on;
        -- do EBS API call 
        /* EBS api call */
        -- custom message in EBS trace output
        apps.hr_utility.trace('Custom message in trace');
        -- custom message in APEX debug
        apex_debug_message.log_message (
          p_message    => 'My message',
          p_enabled    => TRUE,
          p_level      => 5
        );
        -- like to work with Tyler Muth's logger package
        -- logger.log('if the logger package is installed, another way to log a message');
        -- run some other code
        /* my custom code */
        -- set trace off
        apps.hr_utility.trace_off;
        -- log the EBS trace data to APEX or custom table
        /* insert the data of the EBS HR Utility PIPE into APEX debug messages */
        /* query debug output in a report or in APEX debug view */
      end if;
    EXCEPTION
    WHEN OTHERS 
    THEN
      -- store your error in some logging/debugging of the above
      -- dbms_output.put_line(sqlerrm);
      apps.hr_utility.trace_off;
    END;


    I hope by reading the code you understand what I think would be a good way to debug your EBS code in APEX. I didn't find the time yet to write an entire EBS-APEX debug package, but maybe some of you already did or if you want to complete the above code, feel free to share it in the comments.

    Happy debugging :-)

    Previous related posts:

    Updating EBS data from APEX using Triggers and APIs (3)

    In the previous posts I showed how to call the EBS APIs in a Page Process of the APEX page.
    Before that post I blogged about using views to query the EBS data. In this post we will do a combination of those techniques.

    In APEX you can develop really fast; e.g. when you create a Form on table with Report, in less than a minute you have an Interactive Report where people can view and analyse the data in different ways. Clicking on the edit link in the report will allow you to update and delete (and create) the data.

    By building your pages manually and creating the fetch and process data manually (as in the previous APIs posts), you lose a bit of productivity. By using updateable views you gain again some development speed. The updateable view technique, which means creating "INSTEAD OF" triggers on top of your views, is not specific for EBS, but you can use in any project (for example in 2006, I blogged about this feature when I was using it in DG Tournament).

    When I tried to create a person or update the email address of a person through my updateable view I received following error:


    Unless I missed a setting in EBS, it looks like the EBS API call I do in the trigger is not really "trigger compatible". When I discussed with Thierry and Paolo they told me about a parameter called p_validate (which changing didn't resolve my issue) and that using pragma autonomous_transaction might work. When I tried my trigger as an autonomous transaction I received following error:


    That error was solved by adding a commit in the trigger.


    So this is my "INSTEAD OF" trigger for the apex_per_people_vw in the APPS schema
    (if you create the trigger on top of the view in your own schema you get an insufficient privilege error, see previous posts how I did the grants)

    create or replace trigger apex_per_people_vw_trg
    instead of insert or update on apex_per_people_vw
    declare
      l_person_id                 number;
      l_assignment_id             number;
      l_per_object_version_number number;
      l_asg_object_version_number number;
      l_assignment_sequence       number;
      l_assignment_number         varchar2(4000);
      l_object_version_number     number;
      l_employee_number           varchar2(4000);
      l_effective_start_date      date;
      l_effective_end_date        date;
      l_full_name                 varchar2(4000);
      l_comment_id                number;
      l_name_combination_warning  boolean;
      l_assign_payroll_warning    boolean;
      l_orig_hire_warning         boolean;  
      -- use of Autonomous Transaction needed for this API
    pragma autonomous_transaction;
    begin
      if INSERTING 
      then
        apps.apex_api_pkg.create_person ( 
          p_hire_date                 => trunc(:NEW.effective_start_date), 
          p_business_group_id         => :NEW.business_group_id,     
          p_last_name                 => :NEW.last_name,     
          p_sex                       => :NEW.sex,
          p_first_name                => :NEW.first_name,     
          p_date_of_birth             => :NEW.date_of_birth,     
          p_email_address             => :NEW.email_address,     
          p_employee_number           => l_employee_number,     
          p_person_id                 => l_person_id,     
          p_assignment_id             => l_assignment_id,     
          p_per_object_version_number => l_per_object_version_number, 
          p_asg_object_version_number => l_asg_object_version_number, 
          p_per_effective_start_date  => l_effective_start_date, 
          p_per_effective_end_date    => l_effective_end_date, 
          p_full_name                 => l_full_name, 
          p_per_comment_id            => l_comment_id, 
          p_assignment_sequence       => l_assignment_sequence, 
          p_assignment_number         => l_assignment_number, 
          p_name_combination_warning  => l_name_combination_warning, 
          p_assign_payroll_warning    => l_assign_payroll_warning, 
          p_orig_hire_warning         => l_orig_hire_warning 
        );
      elsif UPDATING 
      then
        l_object_version_number := :OLD.object_version_number;
        apps.apex_api_pkg.update_person_email (
          p_effective_date            => trunc(:NEW.effective_start_date),
          p_datetrack_update_mode     => 'CORRECTION',
          p_person_id                 => :OLD.person_id,
          p_email_address             => :NEW.email_address,
          p_object_version_number     => l_object_version_number,
          p_employee_number           => l_employee_number,
          p_effective_start_date      => l_effective_start_date,
          p_effective_end_date        => l_effective_end_date,
          p_full_name                 => l_full_name,
          p_comment_id                => l_comment_id,
          p_name_combination_warning  => l_name_combination_warning,
          p_assign_payroll_warning    => l_assign_payroll_warning,
          p_orig_hire_warning         => l_orig_hire_warning
        );  
      end if;
      -- as we user autonomous transaction a commit or rollback is necessary
      commit;
    exception
      when others
      then
        rollback;
    end;


    On page 10 of the Oracle whitepaper about the integration of E-Business Suite and APEX you find another working example of the updateable view method with the FND_FLEX_VAL_API without an autonomous transaction.

    So which technique is best? Using updateable views or call the APIs from the Page Processes?
    It depends, they have both advantages and disadvantages, but sometimes you don't have a choice and can't use the trigger method.

    Advantages using triggers:
    • Code in one place regardless which APEX page/process inserts/updates/deletes on the view
    • Able to use the APEX wizards to build report and form on top of the view with build-in APEX processes
    Disadvantage (or things you should know) using triggers:
    • Not every EBS API seems to work through triggers
    • Might need to use Autonomous transaction in your trigger to get it working, but what are the side effects? (especially as I don't know what is going on inside the EBS API call)
    • Recreating the view will lose the trigger, so make sure you can recreate the trigger
    • APEX automatic row locking might interfere with EBS locking (the Oracle whitepaper doesn't mention anything of that, but Paolo posted a comment about this, also see documentation of FSP_DML_LOCK_ROW - I didn't experience this yet)
    • Other people might not know about those triggers, so make sure it's clear to who you work with or who will take over the project to tell him you use triggers 
    • Read Tom Kyte's article about triggers, so you know when to use/not use them

    Advantages using custom process
    • Full control when you want to run some code
    • Works regardless of EBS API
    • Different logic possible on different screens on the same data
    • Easier to debug (how much time a process takes, debug output etc.)
    Disadvantages using custom process
    • Takes more time to build the pages and processes manually. There is a wizard to build on top of a procedure too, but I find that still slower than if you can use the wizard to build on top of a view/table.
    • More code if you need to call the same procedure on multiple pages

    If you experienced other advantages/disadvantages, feel free to comment.


    Previous related posts:

    Wednesday, February 08, 2012

    APEX SQL Workshop and Wizards issues in EBS environment

    E-Business Suite (EBS) is a beast... it's the biggest environment I've ever seen.
    If you run this query in the APPS schema:


    select object_type, count(*)
      from user_objects
    group by object_type
    order by 2 desc


    This is the result:


    Over 50,000 packages, over 40,000 synonyms, over 30,000 views in one schema... impressive!

    As I don't have direct access to the Oracle EBS database, I do everything through APEX.
    I setup two workspaces, one linked to the APPS schema, where I only use SQL Workshop to access the objects and another workspace which holds my applications and database objects and grants to some objects in the APPS schema.

    The issue with the Object Browser in SQL Workshop (in APEX) is that it will only show 10,000 objects.
    So there is a chance that if you create your own view, synonym or package that you won't see it.
    (There are ways to increase this limit, but as it's unsupported I won't mention how. And you would need to have access to the web server to make the change, which you might not have either.)


    Even if you try to filter the result, it won't show up. Obviously you won't see many environments having over 10,000 objects in one schema, but I thought to post it anyway as some other EBS customers might hit the issue too and maybe when the Public Oracle Cloud is online and you do everything through the APEX screens you might hit this issue too (if it was an EBS environment for example).

    So how do you get around this? If you want to change your view or you want to see the definitions of that view you can do:

    select text
      from user_views 
     where view_name = 'PER_PEOPLE_F'

    You can copy the definition, make the change and run it in SQL Workshop > SQL Commands to update your view. Querying the user_objects will show you all the objects for example starting with APEX:


    select *
      from user_objects
     where object_name like 'APEX%'


    For packages (and package bodies) it's a pain, especially if you want to develop those packages online. If you can't select the package you don't have the nice editor in APEX, so it makes development a bit harder. You could argue you should do development in for example Oracle SQL Developer or others, but in my case I didn't have direct access to the database, only through a browser...


    The other issue I encountered was in the APEX wizards when I created a Form on a Procedure, when the package/procedure resides in the APPS schema. It kept spinning and spinning and after a couple of minutes I just closed my browser because I didn't want to wait longer.


    I guess it's because the APPS schema is so big and reading from the data dictionary takes a long time, potentially even longer than the web server timeout.

    The workaround here is to add a blank page, create an HTML region and add your items manually.
    Also don't forget to add your process to the page to fetch and/or store the record.


    Hope that helps some people who can't find their objects in SQL Workshop or who find the wizard is slow or doesn't complete in an EBS environment.

    Release of 3.1 versions of SQL Developer and Modeler

    It looks like today was releasing day for the Oracle SQL Developer team:

    You can download Oracle SQL Developer 3.1 (07) or read on the new features e.g. DBA Utilities, Datapump wizard, a new Database Diff, ...


    And also Oracle SQL Developer Data Modeler got a new version: 3.1.0 (700) which hold some new features like synchronisation between model and data dictionary and versioning of designs. You can download it here.


    Installation and migration of settings of my previous version went without any issues. I couldn't live without those tools anymore.