Blog PostsStatistics Feedback About Login  


Go

Blog Selection


Highlight Selected Row
4
Denes Kubicek 23-JUL-2010 10:08

This may be an a bit old topic. However I am getting emails from time to time asking how to do that. This example shows how to easily highlight a selected row in a report and make it persistant while reloading / submitting the page.


Show Comments (0)

Moving your XLIFF Files
4
Joel Kallman 23-JUL-2010 00:15

The XML translation files generated from Oracle Application Express are produced in XML Localization Interchange File Format (XLIFF) format. XLIFF is a recognized standard for the localization of computer software. "It is intended to give any software provider a single interchange file format that can be understood by any localization provider."

One of the unique characteristics of Application Express is that it is one of the few development frameworks where the decision to localize and translate an application can be made after the application is actually completed. Because the definition of the application is maintained in meta data in the APEX repository, it's already known in advance which attributes of your application are translatable and which are not.

The process to produce a translated application is pretty straightforward. It's as simple as:

  1. Seed the translation repository from your existing application
  2. Export the XLIFF file
  3. Translate the XLIFF file
  4. Upload the XLIFF file
  5. Apply the XLIFF file
  6. Publish your translated application

The first few translation unit lines of a sample XLIFF file generated from Application Express look like:



Logout
Logout


Print
Print


Logout
Logout


Print
Print


Home
Home


Customers
Customers


Products
Products


Orders
Orders


Charts
Charts




Each translatable string is included as a 'trans-unit' in the XLIFF file. The last two elements of each translation unit ID are the meta data ID and the application ID. For example, in translation unit with id S-4-885632445599895776-25721, the meta data ID is 885632445599895776 and the application ID is 25721. (S-4 is an internal code signifying that this is a meta data string and corresponds to the text of a tab).

As I've discussed in a recent blog post about saved Interactive Reports, I explained how the internal meta data IDs "shift" or are recalculated when importing an application to a new ID. And this has presented problems for those customers who make use of the translation facilities of Application Express. Because the meta data IDs are a part of the XLIFF translation unit IDs, when those IDs change, the existing XLIFF files for the original application cannot be used against a new version of the application imported elsewhere as a new application ID. What a dead end!

I have authored an APEX application which helps customers overcome this problem. You can run the hosted version of the XLIFF Transformation application which is running in my workspace on apex.oracle.com, or you can download a copy of it and run it on your own APEX 4.0 or later instance. You need to provide 3 things when running this application:

  1. The original XLIFF file
  2. The application ID of the new application
  3. The offset value between the two applications

To compute #3, I'll refer you to this same blog post where I give a couple examples how to determine the offset value.

The logic is really quite simple. After importing the application and installing the supporting objects, only 3 objects will be created - a table named XLIFF_FILES, a trigger on this table, and a small PL/SQL package named XLIFF_TRANSFORM. The PL/SQL package parses the XML file and uses some XDB APIs to replace certain elements of the XML file. By exploiting the native functionality of the database, this was really quite easy to write. For anyone who says the Oracle database is only good for "persisting data", I say smoke this!

This isn't my ideal solution. In a future release of Application Express, I'd like to make it as simple as choosing to include your translations in your application export file, and they move around with you. As the metadata gets transformed on a new import, so do the translations. But until then, this solution can be used.

Show Comments (0)

Webinar – Oracle Application Express Plug-ins
4
Dan Mcghan 21-JUL-2010 09:42

I’ll be hosting another free webinar next week titled Oracle Application Express Plug-ins. The webinar will run on Wednesday, July 28th from 1pm to 2pm EDT. Click here to register.

Abstract

If you use Oracle Application Express then you have probably heard of "plug-ins" by now. But you may still have some unanswered questions, such as:

  • What exactly is a plug-in?
  • What can plug-ins do for me?
  • What plug-ins are available?
  • How do I install and use plug-ins?

These questions and more will be answered during this webinar. This will be a high level introduction to plug-ins during which we will demonstrate how plug-ins can save your organization time and money by easing development efforts. Attendees will receive a copy of the next SkillBuilders plug-in – one week before its general release to the public.

Audience

Anyone interested in Oracle Application Express.

Language

English


Show Comments (0)

Report filtering with APEX 4.0, dynamic action style
4
Anthony Rayner 21-JUL-2010 08:45

I've just got back from the APEX SIG event in Birmingham. As ever, the event was well organised and attended and it's always good to catch up with the extremely knowledgable and enthusiastic UK APEX community. If you haven't yet attended one of these events then I'd definitely recommend them, you will undoubtedly learn something new, make some great contacts and enjoy the day! The next event is planned for 3rd November at the Oracle City Office in London, so if you're interested in coming along, please see here.

Down to business. During the event I was asked whether dynamic actions in APEX 4.0 can handle Ajax based filtering of report data. The answer is yes, so thought I'd make the most of the train journey home to blog about how. The approach is slightly different depending on whether you're dealing with classic or interactive report regions. In this post, I will detail the steps to achieve this with Interactive Report Regions (IRRs), fully declaratively without coding 1 line of JavaScript.


You can also see this working in my sample application here. This example shows a report on the EMP table, with quick filters available to filter by department or job via Ajax, partial page refresh.

The following steps assume that you have the EMP and DEPT tables in your current schema.


With IRRs, the basic approach involves the following 4 steps:
  • Create a page with a report region, ensuring the page item filters are referenced in the SQL.
  • Create the page items for filtering.
  • Create the dynamic action to fire whenever any of the page item filters change value, to refresh the IRR.
  • Define the IRR to save these items values in session state after it is refreshed.

Now let's walk through these steps in detail.
  • Create the page
    1. Within an application, click the 'Create Page' button.
    2. Select 'Report', click 'Next'.
    3. Select 'Interactive Report', click 'Next'.
    4. For 'Page Attributes', enter 'Employee Report' for 'Page Name' and 'Region Name'. Importantly, you must also ensure that the 'Region Template' is set to some template that contains the #REGION_STATIC_ID# substitution string, otherwise this example will not work (dynamic actions need this ID to be able to perform the refresh). Most of the new themes now default to an appropriate template when creating new IRRs (as defined by the new Theme 'Region Default' for 'Interactive Reports'). However if you're using an old theme then you may need to select an appropriate template (try 'Region without Buttons and Title'). Also make a note of the page number (I'll assume page 1 for these steps) and click 'Next'.
    5. For 'Tab Attributes', leave as default and click 'Next'.
    6. For 'Enter a SQL SELECT Statement', enter the following query (referencing the page number noted in step 4 when defining the item names) and click 'Next':


      select e.empno,
      e.ename,
      d.dname,
      e.job,
      e.hiredate,
      e.sal,
      e.comm
      from emp e,
      dept d
      where e.deptno = d.deptno
      and e.deptno = nvl(:P1_DEPTNO, e.deptno)
      and e.job = nvl(:P1_JOB, e.job)
    7. Click 'Finish'.
    8. For purposes of this example, we're going to switch off the standard 'Search' bar to keep things clean. You can do this by right clicking on the 'Employee Report' in tree view and selecting 'Edit Report Attributes'. Then in the 'Search Bar' region, select 'No' for 'Include Search Bar' and 'Apply Changes'.
    If you now click 'Run Page', you'll see the basic report page as been created. We now need to add the page item filters.
  • Create the page items
    1. Go to edit the page. We'll create these items in a separate 'Quick Filters' region above the IRR. In 'Tree View', right click on the region position where the IRR has been created (by default this is 'Body (3)' and select 'Create'.
    2. Select 'HTML' and click 'Next'.
    3. Select 'HTML' and click 'Next'.
    4. For 'Title', specify 'Quick Filters', for 'Region Template' select 'Report Filter - Single Row' and amend the 'Sequence' to be say 5, so that this appears before the IRR on the page, click 'Next'.
    5. For 'Region Source', leave blank and click 'Create Region'. This has created a blank region, that will be the container for our filter items. We'll create 2 filters, to filter the employee report by the job and department columns respectively.
    6. In 'Tree View', right click on the 'Quick Filters' region and select 'Create Page Item'.
    7. Select 'Select List', click 'Next'.
    8. For 'Item Name', enter 'P1_DEPTNO', click 'Next'.
    9. For 'Item Attributes', accept defaults and click 'Next'.
    10. For 'Settings', accept defaults and click 'Next'.
    11. Ensure 'Display Null Value' is 'Yes'.
    12. For 'Null Display Value' enter '- Show All -'.
    13. Leave 'Null Return Value' leave as blank, this will be treated as a true null by APEX.
    14. For 'List of Values Query', enter the following query and click 'Next':


      select dname d,
      deptno r
      from dept
      order by 1
    15. For 'Source' accept defaults and click 'Create Item'.
    16. Now for the job select list. In 'Tree View', right click on the 'Quick Filters' region and select 'Create Page Item'.
    17. Select 'Select List', click 'Next'.
    18. For 'Item Name', enter 'P1_JOB', click 'Next'.
    19. For 'Item Attributes', accept defaults except for the 'Begin on New Line' attribute. We want to set this to 'No', so that the filters appear on the same line in the 'Quick Filters' region. Click 'Next'.
    20. For 'Settings', accept defaults and click 'Next'.
    21. Ensure 'Display Null Value' is 'Yes'.
    22. For 'Null Display Value' enter '- Show All -'.
    23. Leave 'Null Return Value' leave as blank, this will be treated as a true null by APEX.
    24. For 'List of Values Query', enter the following query and click 'Next':


      select distinct job d,
      job r
      from emp
      order by 1
    25. For 'Source' accept defaults and click 'Create Item'.
    If you run the page now, you'll see all the basic page components are created, the regions and the items, but selecting different values from the filters has no effect. We now need to bring these to life.
  • Create the dynamic action
    1. Go to edit the page. Right click on the 'Dynamic Actions' tree node and select 'Create'.
    2. Select 'Advanced' for the 'Implementation'. We need 'Advanced' here because 'Standard' only supports the 'Show', 'Hide', 'Disable' and 'Enable' actions.
    3. For 'Name', enter 'QUICK FILTER REFRESH', click 'Next'.
    4. For 'When', leave the event as 'Change' and for 'Item(s)', enter 'P1_DEPTNO,P1_JOB'. Leave 'Condition' as 'No Condition'. These selections define the dynamic action will fire whenever either the department or job select list's value changes. Click 'Next'.
    5. For 'Action', select 'Refresh' under the 'Component' category in the select list. The 'Refresh' action currently supports IRRs, classic reports, all item types with cascading LOV support and may also support item or region plug-ins, depending on whether the plug-in author has coded the plug-in to support this (the plug-in documentation should state if this is supported). Charts in APEX 4.0 are not yet supported.
    6. Ensure the 'Fire on Page Load' checkbox is unchecked, there is no need to refresh the report when the page loads, it's already fresh. Click 'Next'.
    7. On the 'Affected Elements' page, we'll define what will be refreshed. Select 'Region' from the 'Selection Type' select list and 'Employee Report' from the 'Region' select list. Click 'Create'.
    If you now run the page, you'll notice that this still isn't working as expected. Actually, the dynamic action is firing, the report is being refreshed, but it is not being scoped by the filter selection. The problem is the values for the filter page items are not being saved to session state and are therefore not set when the report's SQL is executed. This is easy to fix.
  • Define the IRR to save these items values in session state after it is refreshed
    1. Right click on the 'Employee Report' and select 'Report Attributes'.
    2. Go the 'Advanced' and for 'Page Items to Submit', enter 'P1_DEPTNO,P1_JOB'. Click 'Apply Changes'.


So that's it, run the page and you will now see the filters are fully functional. Select different jobs and departments and see the report refresh, showing employees scoped by your selections. This example could be easily extended to have different item types used as the filters, not just select lists. A common example would be a slider component where you select a value or range of values, upon which the report is refreshed with rows specific to your selection. I will try and add that to my sample application when I can.

For classic reports, this is slightly more complicated than as outlined above, as there is no 'Page Items to Submit' attribute (yet!!), so you need to save the values in session state in a slightly different fashion. I will try and add that too when I can. (Hint: Instead of defining the IRR 'Page Items to Submit' as detailed in the last bullet, use the 'Execute PL/SQL Code' action within the dynamic action, to fire before the 'Refresh' action. Just leave the code as 'null;' and set the 'Page Items to Submit' attribute to your page items. This will work, but unfortunately issues 2 Ajax calls to do so, which is not optimal.)

Also, if you're interested in seeing more examples of refreshing reports with dynamic actions, I have a couple of others in the sample application:
  1. Refresh - Showing an alternative approach for user's to select their 'Saved Reports' in IRRs. Instead of using the default select list in the search region, this has been switched off in favour of a separate report on the left of the page containing the saved reports available to the current user. This report also shows a tooltip for the report description (if defined), when hovering over the report name. The dynamic action is used to refresh this saved report list, so if a user saves a new report or deletes a report, the report list is updated. Again this is all via Ajax and does not require any manual JavaScript coding.
  2. Refresh 2 - Showing how report row deletion can be handled via Ajax with dynamic actions. This example does require a couple of places within dynamic actions where a line of JavaScript is required.

To learn more about these examples, please download the application, install in your workspace and have a closer look.
Show Comments (0)

Oracle APEX 4.0 Workshop in Wien
4
Peter Raganitsch 21-JUL-2010 07:28

This posting deals with a Workshop in Vienna, Austria, and is in german only. Von 13.-18. September 2010 veranstalten wir eine Workshop-Reihe zur neuen Oracle APEX Release 4.0 . Diese Reihe besteht aus 6 einzelnen und individuell buchbaren Tagen, jeder mit einem eigenen Thema und in sich abgeschlossen. Nützen Sie diese seltene Gelegenheit und lernen
Show Comments (0)

while :new.apex = :old.discussions loop (Loop : 2)
4
Jason Aughenbaugh 20-JUL-2010 23:46

Objectivity is in the Eye of the Beholder

Everything one encounters in life is subjective to our particular point of view. Be it social, political, theological, or theoretical; all people tend to see things different from others. Likewise, organizations of people tend to operate under the same dictionary as others with slightly to more different definitions. Take the term ‘Enterprise’, for instance.

When thinking of the idea of Enterprise software or software development most people might assume that the application would be produced using some really complicated development tools like .NET or JAVA. At the time when I encountered Application Express (HTML-DB at the time) I was thinking roughly the same thing. A few years later Oracle published a slide deck that show many things, but the one slide that catches the most attention when I show it is this one : (Slide 11)

clip_image002

This graphic seemed to capture what many developers, including myself, had been saying for a while. APEX is a development platform that is accessible to all levels of business application development. With one exception that many of us felt very strongly that APEX deserved to be shown as penetrating further into the Enterprise development portion of the business.

APEX can run with the big kids, too

Why, or better, why not? I hadn’t truly gotten it until I had a conversation with a few members of the development team a few months ago. The reason for this disparity seems to exist in the difference in dictionary between what is called Enterprise Software Development and what many businesses call Enterprise Systems.

Depending on your definition APEX is, or is capable of producing, an Enterprise system. Many companies I have encountered express this as an application or series of related applications that service multiple business units and/or multiple business locations or sites. Being that it is a multi-target application development toolset APEX fits this definition very well in both the development tools and the applications it can produce.

Where it comes to Enterprise Software Development, I have heard, APEX doesn’t fit the bill entirely. Since this methodology apparently requires multiple developers to be working on multiple units of the whole system in order to complete the final product, with source control and documentation. In the previous post I spoke about methodologies and the fact that given the right amount of control any development toolset can succeed or fail equally. Either way, the newer enhancements to APEX seem to suggest that it fits this definition more today than it did even six months ago.

There is but one other definition of Enterprise that comes to mind and it is a really poignant one. It is that large companies, the ones that Enterprise Software is usually targeted toward, are rarely enterprising anymore. They don’t take the risks that make up this definition. They have resources that make buying a Commercial (“Enterprise”) Solution for everything possible and therefore they are more stagnant, less flexible and less open to change. This is a very good spot to be for the APEX platform. It sports the power and security of an Oracle Database. As a multi-target solution it can produce a suite of business applications for the business that can fit just about every conceivable need and can be supported by a minimum of personnel. It enables the organization that employs it to concentrate resources into common effort that can free up other resources to work forwarding the business rather than supporting excessively diverse IT systems.  While doing so with a lower cost of ownership than other tools.

In the end, I find that APEX fits my definition of being suitable and scalable to any Enterprise. Other opinions may vary.

Cheers! :”)

Show Comments (0)

while :new.apex = :old.discussions loop (Loop : 1)
4
Jason Aughenbaugh 20-JUL-2010 21:23

Welcome Version 4.0

Oracle Application Express (APEX) 4.0 arrived this month with anticipation and fanfare equivalent to a really large family reporting on a new grandchild being born. Having had a bit of time to explore and experiment with the new version I am more than impressed with this new and large step forward in the product. After a few weeks of beating up these new enhancements it has become clear that this software is going to be a force to be reckoned with for some time to come.

This latest release has brought some old conversations back to the surface in the many political, social, and techno-theological aspects of the business and IT organization that employs this software. (or finds that it is being employed ;”)

To RAD or not to RAD

Rapid Application Development (RAD) has been a subject of contention in the business realm for a few years now. It’s not to say that RAD is bad; just that it takes a certain understanding that it can and will get messy, if it is not controlled properly. Not all, in fact most, organizations should not use this methodology of software development because of this fact. (insert ‘popular OS’ joke here)

As a result of personal or organizational experience with RAD, many IT Architects shun any tool from the IT portfolio that has been remotely associated with RAD. The issue here is that RAD is a methodology not a programming toolset. One can, conceivably, use RAD with .NET and JAVA to create the same mess that they can get into with any other application development toolset available.

APEX has fallen prey to this misconception before and likely will again until some of the detractors actually sit down with it and understand that normal, organized, documented, and controlled application development can be done with it to produce functional, secure, scalable, and stable applications with it. APEX is not RAD but it is Radical in that it allows a team to use their own methodologies in the creation of a business application. In my experience APEX has the overwhelming advantage of producing the application quicker than the other options available.

Be it RUP, SDLC, RAD, Agile, or any other methodology, a toolset has to be used to create the application, but that toolset is not the methodology and likewise.


Show Comments (0)

Where Did My Saved Interactive Reports Go?
4
Joel Kallman 20-JUL-2010 16:27

A problem I've seen reported numerous times from customers is that users' saved (or customized) interactive reports are missing after they import a new version of their application. This is a problem we've known about for a while with no adequate remedy. However, given the introduction of the APEX_APPLICATION_INSTALL API in Application Express 4.0, I can offer a solution. Granted, it's not an ideal answer but it's certainly a feasible and supported solution. Firstly, some explanations are in order.

When an APEX application is imported into a workspace, the very first thing that's done is the existing version of the application is completely deleted. All of the meta data associated with the application is deleted - the definition of the pages, the reports on the pages, the templates, the buttons, the branches, the shared components, everything - it's all deleted. Once this is complete, then the application meta data of the APEX application being imported is then inserted. This whole process is atomic - so if an error occurs, the transaction is rolled back and the net effect is no change.

In the case of saved Interactive Reports, it's a little bit different. Imagine you have a production instance running application 645 - you have numerous users who have saved many Customized Interactive Reports. Upon import of a new version of the application, all meta data associated with application 645 is first deleted except the Customized Interactive Reports. In essence, these are left "dangling" until the new application 645 is installed. Once the application import is complete, then the meta data of the Customized Interactive Reports will reference real interactive report definitions again.

But there's a catch. If the application ID changes upon import, then this results in totally new meta data IDs being generated. (This is done in an attempt to prevent collisions of meta data, so you can freely export your application and give to anyone in the world to use on their own APEX instance). A meta data offset number is randomly generated and added to all of the existing IDs. This is done uniformly across all of the application meta data (this is important, and you'll see why shortly). Since the IDs of all of the application meta data have changed, all of your users' customized reports in the previous version of the application are forever left orphaned until they're cleaned up by an internal APEX batch process. Yikes!

Let's look at an example. On apex.oracle.com, I created a simple application with an Interactive Report on the EMP table. I defined this application as application 70000. I then exported this application and imported it back as application 70001.

Using SQL Commands and the APEX Data Dictionary views, I ran the following queries:


select tab_label, tab_id
from APEX_APPLICATION_TABS
where application_id = 70000

tab_label: Emp
tab_id: 1573281607527253166


select tab_label, tab_id
from APEX_APPLICATION_TABS
where application_id = 70001

tab_label: Emp
tab_id: 3146580610985521585

And the difference between the two IDs is 3146580610985521585 - 1573281607527253166 = 1573299003458268419


Let's do this again, but this time, for the APEX data dictionary view for page templates:

select template_id from APEX_APPLICATION_TEMP_PAGE where template_name = 'Login' and application_id = 70000

template_id: 1573270610302252883


select template_id from APEX_APPLICATION_TEMP_PAGE where template_name = 'Login' and application_id = 70001

template_id: 3146569613760521302


If we once again compute the differences between these two IDs, we get: 3146569613760521302 - 1573270610302252883 = 1573299003458268419

This happens to be exactly the difference between the IDs of all of the application meta data, with the exception of the application and page IDs. All of the meta data is consistently "pushed" or offset to a new value.

How is this relevant to missing saved Interactive Reports? Simple. Since we're able to compute the offset which was used between the two applications, if we had a way to ensure that the same offset is used every time upon application import, then there would be no issue with the old saved Interactive Report IDs matching with the newly imported meta data. They would be married again. And how is this done? In Application Express 4.0, there is a new API named APEX_APPLICATION_INSTALL which enables you to control this offset value.

To ensure that I didn't lose the saved Interactive Reports on subsequent imports of application 70000 to application 70001, I included the computed offset before importing this application via SQL*Plus:


begin
apex_application_install.set_application_id( p_application_id => 70001 );
apex_application_install.set_offset( p_offset => 1573299003458268419 );
--
-- set the alias so it doesn't collide with the alias from app 70000
--
apex_application_install.set_application_alias(
'F' || apex_application.get_application_id );
end;
/


@f70000.sql


That's all there is to it. Note that I didn't have to call apex_application_install.set_workspace_id above, because application 70000 and 70001 are in the same workspace where I performed this test.

As I stated earlier, this isn't the most elegant solution on the planet and most people don't want or need to know about meta data IDs or offsets or any of this complexity. But for those experienced users who are stuck with this problem of losing saved interactive reports when migrating from one application ID to another or across workspaces or instances, this is a supported and feasible solution.





Show Comments (0)

"Rekursive" Table Functions: Ohne Objekttypen
4
Carston Czarski 20-JUL-2010 09:09

English title: Recursive able Functions - without object types!

Erst vor kurzem hatte ich ein wenig was über die neue rekursive WITH-Klausel gepostet. Diese ist ab Version 11.2 verfügbar und erlaubt es, hierarchische Abfragen ohne START WITH - CONNECT BY zu formulieren.
Only a short time ago I posted about the new recursive subqueries, which are available in 11.2 and which allow to do recursive queries without START WITH - CONNECT BY.
Interessant ist, dass diese Technik es auch erlaubt, Table Functions auf eine andere Art zu bauen - man kann sich so eine SQL-Abfrage schreiben, die mit Hilfe der Rekursion zusätzliche Tabellenzeilen generieren kann. Hier ein Beispiel: Den Tilgungsplan, der hier als "klassische" Table Function bereitsteht, kann man auch mit einer rekursiven WITH-Klausel bauen. Das sähe dann so aus ...
The interesting bit is that this kind of query could also be used as a replacement for table functions - the recursion allows to create new, "table-independent" rows in a query result. And here is an example: I've done the table function for the "mortgage plan" as a recursive query. This query looks like this ...
col kapital format 999999990D00
col zinsen format 999999990D00
col tilgung format 999999990D00
col restwert format 999999990D00

with konstanten (datum, kapital, zinssatz, rate, rhythmus) as (
  select 
    trunc(sysdate, 'MONTH') datum,
    100000 kapital,
    5 zinssatz,
    600 rate,
    1 rhythmus
  from dual
), 
tilgungsplan (datum, kapital, zinsen, tilgung, restwert) as (
  select 
    to_char(k.datum) datum,
    k.kapital, 
    k.kapital * k.zinssatz / (100 * (12 / k.rhythmus)) zinsen,
    k.rate - k.kapital * k.zinssatz / (100 * (12 / k.rhythmus)) tilgung,
    k.kapital - ( k.rate - k.kapital * k.zinssatz / (100 * (12 / k.rhythmus))) restwert
  from konstanten k
  union all (
   select 
    to_char(add_months(to_date(s.datum),k.rhythmus)) datum,
    s.restwert kapital,
    s.restwert * k.zinssatz / (100 * (12 / k.rhythmus)) zinsen,
    least(
      k.rate - s.restwert * k.zinssatz / (100 * (12 / k.rhythmus)),
      s.restwert
    ) tilgung,
    s.restwert - ( 
      least(
        k.rate - s.restwert * k.zinssatz / (100 * (12 / k.rhythmus)),
        s.restwert
      )
   ) restwert
   from konstanten k, tilgungsplan s
   where restwert > 0 
  )
)
select * from tilgungsplan
/
Der Vorteil ist, dass man keine Objekttypen zum Beschreiben der Ergebnismenge mehr braucht - man kann eine solche Abfrage mit nichts weiter als einem CREATE SESSION-Privileg ausführen. Allerdings sind die "klassischen" Table Functions (im Moment noch) wesentlich schneller - wer möchte, kann es ja vergleichen. Man kann auf jeden Fall festhalten, dass man mit der rekursiven WITH-Klausel mehr machen kann, als Parent-Child-Beziehungen abzufragen ...
As an advantage you don't need to create object types (which you need for pipelined table functions) - so this query could be executed with just the CREATE SESSION privilege. But (currently) this query is significantly slower than the pipelined function. And the result of all this ...? Using the new recursive WITH clause you can do much more than just querying parent-child relationships.

Show Comments (0)

APEX_APPLICATION_INSTALL
4
Joel Kallman 20-JUL-2010 07:55

Overview


Oracle Application Express provides two ways to import an application into an Application Express instance:

  1. Upload and installation of an application export file via the Web interface of Application Express.
  2. Execution of the application export file as a SQL script, typically in the command-line utility SQL*Plus

Using the file upload capability of the Web interface of Application Express, developers can import an application with a different application ID, different workspace ID and different parsing schema. But when importing an application via a command-line tool like SQL*Plus, none of these attributes (application ID, workspace ID, parsing schema) can be changed without directly modifying the application export file.

As more and more Application Express customers create applications which are meant to be deployed via command-line utilities or via a non-Web-based installer, they are faced with this challenge of how to import their application into an arbitrary workspace on any APEX instance.

Another common scenario is in training classes, to install an application into 50 different workspaces, all using the same application export file. Today, customers work around this by adding their own global variables to an application export file (never recommended and certainly not supported) and then varying the values of these global variables at installation time. However, this manual modification of the application export file (usually done with a post-export sed or awk script) shouldn't be necessary - and again, not supported.



In Oracle Application Express 4.0, there is a new API available named APEX_APPLICATION_INSTALL. This PL/SQL API provides a number of methods to set application attributes during the Application Express application installation process. All export files in Application Express 4.0 contain references to the values set by the APEX_APPLICATION_INSTALL API. However, the methods in this API will only be used to override the default application installation behavior.


APEX_APPLICATION_INSTALL Summary


Workspace


Used to set and get the workspace ID for the application to be imported. This number can be determined by querying the view APEX_WORKSPACES.

procedure set_workspace_id( p_workspace_id in number );

function get_workspace_id return number;


Application ID


Used to set and get the application ID for the application to be imported. The application ID should either not exist in the instance, or if it does exist in the instance, it must be in the workspace where the application will be imported into. This number must be a positive integer and must not be from the reserved range of Application Express application IDs.

procedure set_application_id( p_application_id in number );

function get_application_id return number;


Generates an available application ID on the instance and sets the application ID in APEX_APPLICATION_INSTALL.

procedure generate_application_id;


Offset


Used to set the offset value during application import. This value is used to ensure that the metadata for the Application Express application definition does not collide with other metadata on the instance. For a new application installation, it's almost always sufficient to call generate_offset to have Application Express generate this offset value for you. This number must be a positive integer.

procedure set_offset( p_offset in number );

function get_offset return number;

procedure generate_offset;


Schema


Used to set the parsing schema ("owner") of the Application Express application. The database user of this schema must already exist, and this schema name must already be mapped to the workspace which will be used to import the application.

procedure set_schema( p_schema in varchar2 );

function get_schema return varchar2;


Name


Sets the application name of the application to be imported.

procedure set_application_name( p_application_name in varchar2 );

function get_application_name return varchar2;


Alias


Sets the application alias of the application to be imported. This will only be used if the application to be imported has an alias specified. An application alias must be unique within a workspace, and it's recommended to be unique within an instance.

procedure set_application_alias( p_application_alias in varchar2 );

function get_application_alias return varchar2;


Image Prefix


Sets the image prefix of the application to be imported. The default can usually be used, as most Application Express instances use the default image prefix of /i/.

procedure set_image_prefix( p_image_prefix in varchar2 );

function get_image_prefix return varchar2;


Proxy


Sets the proxy server attributes of the application to be imported.

procedure set_proxy( p_proxy in varchar2 );

function get_proxy return varchar2;


Clear


Clears all values currently maintained in the APEX_APPLICATION_INSTALL package.

procedure clear_all;




Examples


Using the workspace FRED_DEV on the development instance, you generate an application export of application 645 and save it as file f645.sql. All examples below assume you are connected to SQL*Plus.

To import this application back into the FRED_DEV workspace on the same development instance using the same application ID:

@f645.sql

To import this application back into the FRED_DEV workspace on the same development instance, but using application ID 702:

begin
apex_application_install.set_application_id( 702);
apex_application_install.generate_offset;
apex_application_install.set_application_alias( 'F' || apex_application.get_application_id );
end;
/

@645.sql

To import this application back into the FRED_DEV workspace on the same development instance, but using an available application ID generated by Application Express:

begin
apex_application_install.generate_application_id;
apex_application_install.generate_offset;
apex_application_install.set_application_alias( 'F' || apex_application.get_application_id );
end;
/

@f645.sql

To import this application into the FRED_PROD workspace on the production instance, using schema FREDDY, and the workspace ID of FRED_DEV and FRED_PROD are different:

declare
l_workspace_id number;
begin
select workspace_id into l_workspace_id
from apex_workspaces
where workspace = 'FRED_PROD';
--
apex_application_install.set_workspace_id( l_workspace_id );
apex_application_install.generate_offset;
apex_application_install.set_schema( 'FREDDY' );
apex_application_install.set_application_alias( 'FREDPROD_APP' );
end;
/

@f645.sql

To import this application into the Training instance for 3 different workspaces (each workspace with their own schema):

declare
l_workspace_id number;
begin
select workspace_id into l_workspace_id
from apex_workspaces
where workspace = 'TRAINING1';
--
apex_application_install.set_workspace_id( l_workspace_id );
apex_application_install.generate_application_id;
apex_application_install.generate_offset;
apex_application_install.set_schema( 'STUDENT1' );
apex_application_install.set_application_alias( 'F' || apex_application.get_application_id );
end;
/

@f645.sql

declare
l_workspace_id number;
begin
select workspace_id into l_workspace_id
from apex_workspaces
where workspace = 'TRAINING2';
--
apex_application_install.set_workspace_id( l_workspace_id );
apex_application_install.generate_application_id;
apex_application_install.generate_offset;
apex_application_install.set_schema( 'STUDENT2' );
apex_application_install.set_application_alias( 'F' || apex_application.get_application_id );
end;
/

@f645.sql

declare
l_workspace_id number;
begin
select workspace_id into l_workspace_id
from apex_workspaces
where workspace = 'TRAINING3';
--
apex_application_install.set_workspace_id( l_workspace_id );
apex_application_install.generate_application_id;
apex_application_install.generate_offset;
apex_application_install.set_schema( 'STUDENT3' );
apex_application_install.set_application_alias( 'F' || apex_application.get_application_id );
end;
/

@f645.sql

Now a final word of caution - with great power comes great responsibility. You should almost never set the offset value yourself unless you absolutely know what you're doing. One of the primary benefits of letting Application Express generate the meta data offset value for you is you avoid the possibility of any "collisions" with the meta data of any other application on any other APEX instance on the planet. If you have no known reason to manually set the offset value, then simply let Application Express set it for you.


In summary, the APEX_APPLICATION_INSTALL API in Application Express 4.0 now enables you to overcome a limitation in all previous versions of Application Express - namely, to take an arbitrary application export file and import it into any workspace on any arbitrary Application Express instance using SQL*Plus or any other command-line tool.

Show Comments (0)

 1 2 3 4 5 6 7 8 9 10 








 
 
Blog Roll
  • APEXtras
  • Ahcene Bourouis
  • Andy Tulley
  • Anja Hildebrandt
  • Anthony Rayner
  • Anton Nielsen
  • Apex Blog
  • Apex dbe pl
  • Ben Burrell (Munky)
  • Bernard Fischer-Wasels
  • Bradley Brown
  • Carl Backstrom
  • Carsten Cerny
  • Carston Czarski
  • Christian Rokitta
  • Christopher Beck
  • Dan Durbaca
  • Dan Mcghan
  • David Njoku
  • David Peake
  • Denes Kubicek
  • Dietmar Aust
  • Dimitri Gielis
  • Dirk McComsey
  • Doug Gault
  • Douwe Pieter van den Bos
  • Duncan Mein
  • E-Dba
  • Eric Boissonneault
  • Evgeny Timoshinin
  • German APEX Community
  • Håvard Kristiansen
  • IAdvise
  • Ilmar Kerm
  • Iloon Ellen
  • Insum
  • Jason Aughenbaugh
  • Jason M.
  • Jason Straub
  • Jean-Phillipe Pinte
  • Jeff Holoman
  • Jeffrey Kemp
  • Joel Kallman
  • John Scott
  • Jon Trostheim
  • Jornica
  • João Oliveira
  • Kristian Jones
  • Learco Brizzi
  • Louis-Guillaume Carrier-Bédard
  • Marc Sewtz
  • Mark Lancaster
  • Martin B. Nielsen
  • Martin Giffy D'Souza
  • Matt Ball
  • Matt Nolan
  • Niels de Bruijn
  • Niels de Bruijn
  • Noel Portugal
  • Oracle Nerd
  • Oracle Quirks
  • Oradude
  • PL/GMaps
  • Patrick Wolf
  • Paul Brookes
  • Paulo Vale
  • Pawel Barut
  • Peter De Boer
  • Peter Manchev
  • Peter Raganitsch
  • Przemek Staniszewski
  • RCI
  • Roel Hartman
  • Rutger de Ruiter
  • Sara Blair
  • Sathish Kumar
  • Scott Spendolini
  • Scott Wesley
  • Stew Stryker
  • Sujay Dutta
  • Sumnertech Blog
  • Tobias Arnhold
  • Tyler Muth
  • Unknown APEX
  • Wei Zheng

    © Created and Hosted by Apex Evangelists