Skip to main content

Command Palette

Search for a command to run...

Tips for APEX Application Constants

How to use Text Messages for Constants

Updated
4 min read

It's very common for APEX application to have application level items (usually these are named APP_... or G_... and are defined in Shared Components > Application Items). For values that are unique to a given user/session application items are a logical place to store them (ex: APP_USER_ID). When the item contains a value a new row is inserted into the apex_application_items table (this is really a view but there's an underlying table that stores the value).

If an application item is constant for the entire application (regardless of user/session) then it may not make sense for a new row to be created to store a session state value. For example, suppose you had the following setup:

  • Application item called APP_NAME

  • Set for each session based on a value in a lookup table

  • In dev you set to Demo Dev, test: Demo Test, and production: Demo

This means that the following would occur for every session:

  • Computation or process on new instance to load value from lookup table

  • A new row is created in apex_application_items for every session

The above steps would happen for every session despite the fact that the value does not change. In smaller systems this may not matter however on higher volume systems or environments with lots of applications this may add additional overhead.

Solution

To avoid the additional overhead you can use a Text Message. Text Messages are primarily intended for translation purposes however they also allow developers to have configurable application constants. Text messages are different than Application Settings in the sense that they can be referenced in APEX as a substitution string.

The following example shows how to use text messages for this purpose.

Go to Shared Components > Text Messages

Click Create Text Message and add the following:

On the login page (or this can be anywhere in the application where you want a dynamic application name) change the region title to: &APP_TEXT$APP_NAME. More information about referencing text messages as substitution strings can be found in docs.

When the page is run it shows Demo Dev as expected:

To change this in other environments it's unrealistic to set the value via the APEX application builder as most developers won't have access to Test and Prod instances. Instead it can be easily set through the API apex_lang.update_message As part of your release process after the APEX application has been update the following code should be run to set the value:

declare
    c_apex_app_id apex_application_translations.application_id%type := 200;
    l_translation_entry_id apex_application_translations.translation_entry_id%type;
begin

    select 
        aat.translation_entry_id
    into 
        l_translation_entry_id
    from apex_application_translations aat
    where 1=1
        and aat.application_id = c_apex_app_id
        and aat.translatable_message = 'APP_NAME'
    ;

    -- Detect if in APEX already
    -- Usually necessary as this should be run as a post-install script in SQLcl
    -- 
    -- If you're not in an APEX application you'll get following error:
    -- ORA-20001: Package variable g_security_group_id must be set.
    -- 
    -- May get ORA-20987: APEX - An API call has been prohibited.
    -- If so go to Shared Components >  Security Attributes
    -- Check box: Runtime API Usage > Modify This Application
    -- 
    if apex_application.g_flow_id is null then 
        apex_session.create_session (
            p_app_id => c_apex_app_id,
            p_page_id => 1,
            p_username => 'dummy'
        );
    end if;

    -- Set text message:
    apex_lang.update_message (
        p_id => l_translation_entry_id,
        -- Note: This value should come from a lookup table
        p_message_text => 'Dev Test'
    );

    -- Commit is required for changes to take affect
    commit;
end;
/

After running this script the login page will show the update application name:

Closing Remarks

I've used this technique in a very high-use application that can have between 300,000 ~ 500,000 sessions a day. The application has about 10 application constants. If Application Items were used for these constants it would result in 10 x 500,000 (5 Million) unnecessary extra writes occurring every day to store values that don't change.

I also found that there were some places "regular" substitution strings did not work (using an Application Item or Page Item) but worked for Text Messages. These were extreme edge cases.

When this technique is used you need to ensure that you have a good release process. I.e. right after the APEX application is installed/updated in each environments the text messages need to be updated as they will contain the "original" text message from the application export.

B

TROPICAL DELIGHT RECOVERY IS THE ONLY VERIFIED LICENSE COMPANY.

Are you looking for a way to recover cryptocurrency you misplaced or had stolen? I'm pleased to inform that Tropical Delight Recovery Hacker has resolved the issue that nearly caused my house to fall since I spent the monies my spouse wanted to utilise to start a business. I lost $1.4 million in bitcoin and etherium to these scammers. They excel at what they do and are the leading certified cryptocurrency recovery company. They can be reached instantly at: @ tropicaldelightrecoveryhacker on Telegram and @ tropicaldelightrecoveryhacker.93 on Signal. The email address is TropicalDelightRecoveryHacker @ out look .com.

R

Very insightful

J

Hi Martin,

I have two cases that like understand does write to database happens:

  1. If I create hidden item P0_APP_NAME to global page and set Storage to Per Request (Memory Only). Then create application computation before header for item.
  2. I have hidden item P1_EMPNO where Storage set Per Request (Memory Only), and I use item in classic report Page Items to Submit. Then e.g. sort report.

Thanks advance.

M

Jari Laine in both cases the items will be written to "APEX Session memory" in the database. Here are the reasons:

1: When you have a application computation, the processing is done in the database and therefore is saved in your APEX Session

2: When the item is set to Page Items to Submit the same occurs. It's sent via the AJAX request, stored in APEX Session then is used in the request.

1
O

Hello Martin, this post is very good. I have a doubt. ¿Can I use this with a computation instead of a application item to save the username? Because I'm using database user and not APEX user

M

Text messages are stored for the entire application (i.e. they aren’t session specific). You shouldn’t use it to store session specific content. So I wouldn’t recommend for username.

1
O

Martin Giffy D'Souza thanks for your response

J
Jon Dixon2y ago

Nice, thanks Martin.