Skip to main content

Command Palette

Search for a command to run...

JavaScript Inside Oracle Database?

My First Impressions of MLE

Updated
7 min read
JavaScript Inside Oracle Database?

When I first heard that Oracle Database could execute JavaScript directly inside the database, my reaction was probably the same as many developers:

Wait... why would I want JavaScript running in my database?

After spending some time exploring Oracle's Multilingual Engine (MLE), I realized that the answer isn't necessarily about replacing PL/SQL. Instead, it's about giving developers another tool for specific scenarios where JavaScript can be more natural, reusable, or easier to integrate with modern applications.

In this article, I'll share what MLE is, how it works, some practical examples, and where I think it can be genuinely useful.


What is MLE?

MLE (Multilingual Engine) is a feature that allows Oracle Database to execute JavaScript code directly inside the database engine.

This means developers can create JavaScript modules, invoke functions from SQL or PL/SQL, and leverage JavaScript without requiring a separate application server.

In simple terms:

  • PL/SQL still exists and remains the primary language for database development.

  • MLE adds JavaScript as an additional option.

  • Both can coexist within the same solution.


Why Is This Interesting?

Most enterprise applications today involve JavaScript somewhere in the stack.

Whether you're building:

  • Oracle APEX applications

  • REST APIs

  • Node.js services

  • Frontend applications

there's a good chance JavaScript is already part of your ecosystem.

MLE creates opportunities to reuse logic closer to the data without having to duplicate code across multiple layers.


Example 1: Formatting Customer Names

Let's start with something simple but practical.

Create a JavaScript module:

create or replace mle module customer_utils
language javascript as export
function formatName(firstName, lastName) {
return `\({firstName.trim()} \){lastName.trim()}`.toUpperCase(); }
/

Now create a PL/SQL wrapper:

create or replace
function get_customer_name(
   p_first_name in varchar2
  ,p_last_name  in varchar2
)
return varchar2 as mle module
customer_utils signature 'formatName(string,string)';
/

Usage:

select get_customer_name( 'Andrés', 'López' ) as customer_name from dual;

Result:

ANDRÉS LÓPEZ

Simple? Yes.

Useful? Maybe not yet.

But it demonstrates how JavaScript can become part of your database layer.


Example 2: Working with JSON

This is where things start becoming more interesting.

Modern applications consume and produce JSON constantly.

Suppose we receive an API payload:

{
  "name": "John",
  "country": "Canada",
  "status": "active"
}

Using JavaScript:

create or replace mle module json_utils
language javascript as

export function getStatus(payload) {
    const obj = JSON.parse(payload);
    return obj.status;
}
/

Now we can extract information directly:

select get_status(
'{
  "name":"John",
  "country":"Canada",
  "status":"active"
}'
)
from dual;

For developers already familiar with JavaScript, this feels very natural.


A Practical Use Case for Oracle APEX

One scenario I found interesting is data transformation before displaying information in APEX.

Imagine receiving data from:

  • REST APIs

  • external integrations

  • third-party services

Instead of creating complex PL/SQL parsing logic, JavaScript can sometimes make transformations easier to read and maintain.

For teams already comfortable with JavaScript, this can reduce development effort.


Advantages of MLE

After experimenting with it, these are the main benefits I see.

Familiar Syntax

Many developers already know JavaScript.

This lowers the learning curve when compared to introducing another language.

Better JSON Handling

JavaScript was built around working with objects and JSON.

Some transformations simply feel more natural.

Code Reuse

Organizations that already have JavaScript business logic may be able to reuse portions of that code.

Modern Development Experience

MLE helps bridge the gap between database development and modern application development practices.


Limitations and Things to Consider

As interesting as MLE is, I don't see it replacing PL/SQL.

At least not anytime soon.

PL/SQL Is Still King

PL/SQL remains deeply integrated with Oracle Database.

For:

  • Transactions

  • Bulk operations

  • Database-centric logic

  • Packages

  • Triggers

PL/SQL continues to be the obvious choice.

New Technology Means New Learning

Many DBAs and Oracle developers have decades of experience with PL/SQL.

Introducing JavaScript into the database requires new skills and new governance practices.

Not Every Problem Needs JavaScript

Just because you can write something in JavaScript doesn't mean you should.

Sometimes a simple PL/SQL function remains the cleaner solution.


Where I Think MLE Makes Sense

After spending time with it, these are the scenarios where I see the most value:

  • JSON transformations

  • API integrations

  • Data validation

  • String manipulation

  • Shared logic across applications

  • Modern development teams already using JavaScript


Can I Use This in Oracle APEX?

Absolutely.

One scenario where I can see MLE being useful in Oracle APEX is when an application consumes data from external APIs and needs to perform transformations before displaying the information to users.

Let's use a realistic example.

Suppose an APEX application receives customer information as JSON from a REST API. The requirement is to display a friendly label combining:

  • Customer name

  • Country

  • Status

Expected Output

John Smith (Canada) - Active

This kind of transformation is common in:

  • REST Data Sources

  • Integration processes

  • Staging tables

  • Dynamic Content regions

  • Interactive Reports

Creating and populating the Table

create table customers (
    customer_id   number
        generated always as identity
        primary key,
    customer_name varchar2(100) not null,
    country       varchar2(100) not null,
    status        varchar2(20)  not null
);
/
insert into customers (
    customer_name,
    country,
    status
)
select *
from (
    values
        ('John Smith',       'Canada',         'active'),
        ('Jane Doe',         'United States',  'inactive'),
        ('Michael Johnson',  'United Kingdom', 'active'),
        ('Emily Brown',      'Australia',      'active'),
        ('David Wilson',     'Mexico',         'inactive'),
        ('Sarah Miller',     'France',         'active'),
        ('Carlos Garcia',    'Spain',          'active'),
        ('Sophie Martin',    'Canada',         'inactive'),
        ('Lucas Dubois',     'France',         'active'),
        ('Maria Rodriguez',  'Colombia',       'active')
) c (
    customer_name,
    country,
    status
);

As a side note, the sample data in this article uses the new multi-row VALUES syntax introduced in recent Oracle Database releases. It's one of those features that won't make headlines, but once you start using it, you wonder why it wasn't there years ago. For quick tests, demos, and proof-of-concepts, it makes populating tables much cleaner and easier to read than some of the alternatives we used in the past.

Traditional PL/SQL Solution

Create a helper function:

create or replace
function format_customer_label(
    p_name    in varchar2
   ,p_country in varchar2
   ,p_status  in varchar2
)
return varchar2
is
begin
    return p_name
           || ' ('
           || p_country
           || ') - '
           || initcap(p_status);
end;
/

Usage:

select
    format_customer_label(
         customer_name
        ,country
        ,status
    ) as customer_label
from customers;

Result:

Perfectly valid.

For many situations, this is probably the solution I would choose.

MLE JavaScript Solution

Now let's build the same functionality using JavaScript.

Create an MLE module:

create or replace mle module customer_formatter_mod
language javascript as

export function formatCustomerLabel(
    name,
    country,
    status
) {

    const formattedStatus =
        status.charAt(0).toUpperCase()
      + status.slice(1).toLowerCase();

    return `\({name} (\){country}) - ${formattedStatus}`;
}
/

Publish the function through a Call Specification:

create or replace function format_customer_label_js (
    p_name    in varchar2
   ,p_country in varchar2
   ,p_status  in varchar2
)
return varchar2
as mle module customer_formatter_mod
signature 'formatCustomerLabel(string,string,string)';
/

Now use it directly from SQL:

select
    format_customer_label_js(
        customer_name
       ,country
       ,status
    ) as customer_display
from customers;

Result:

MLE modules expose JavaScript functions and make them callable from SQL and PL/SQL through call specifications, allowing them to be used much like ordinary database functions.


My Take

I don't think MLE is trying to replace PL/SQL.

And honestly, it shouldn't.

What I do think is that Oracle recognizes how modern development teams work today. JavaScript has become one of the most common languages in the industry, and allowing developers to use it closer to the data opens some interesting possibilities.

Will every Oracle developer start writing JavaScript inside the database tomorrow?

Probably not.

But for teams building modern applications, especially those combining Oracle Database, Oracle APEX, REST APIs, and JavaScript-based services, MLE is definitely worth exploring.

At the very least, it's one of the most surprising features Oracle has introduced in recent years—and one that I suspect we'll be hearing much more about in future releases.

"Would you use JavaScript inside the database, or would you rather keep business logic in PL/SQL?"