MySQL 9.0: Writing Stored Procedures with JavaScript Instead of Pure SQL

MySQL tutorial - IT technology blog
MySQL tutorial - IT technology blog

MySQL 9.0 and the JavaScript Breakthrough

Handling business logic with pure SQL in Stored Procedures (SPs) has always been a “nightmare” for many developers. Syntaxes like DECLARE, BEGIN...END, or WHILE loops are often rigid and difficult to debug. I once managed an e-commerce system with an orders table of over 10 million rows. At that time, calculating tiered discounts using SQL Procedures was a disaster—the code was long, error-prone, and extremely hard to maintain.

With version MySQL 9.0, MySQL integrated the Multilingual Engine (MLE) based on GraalVM. This change allows you to write business logic directly within the database using JavaScript (ECMAScript 2023). This isn’t just a new feature; it’s a more modern approach to in-place data processing.

Comparing Business Logic Processing Methods

To see if JavaScript Stored Procedures are worth the upgrade, let’s look at three common approaches:

1. Processing at the Application Layer (Node.js, Python, Go…)

  • Pros: Easy to write unit tests, leverages a massive ecosystem of libraries.
  • Cons: You have to pull data from the DB to the App over the network. If you need to process 500MB of data just to get a single total, the latency will significantly slow down the system.

2. Traditional SQL Stored Procedures

  • Pros: Runs directly in the DB, no data transfer overhead.
  • Cons: Outdated syntax, extremely tedious string and JSON manipulation, and poor code reusability.

3. JavaScript Stored Procedures (MySQL 9.0+)

  • Pros: Combines the power of JS (smooth JSON handling) with in-place execution performance.
  • Cons: Currently only available in MySQL 9.0 Enterprise or the latest Community version. GraalVM also requires proper RAM allocation.

Why Should You Consider Switching to JavaScript?

Here are 3 reasons why I decided to bring JS into the database:

  1. Native JSON Manipulation: JS was born for JSON. While SQL requires cumbersome JSON_EXTRACT functions, JS allows you to access properties just like a regular object.
  2. Modern Syntax: You can use map, filter, and reduce to process datasets. These functions make the code much more concise and readable than archaic SQL loops.
  3. Abundant Resources: Finding a developer proficient in JS is much easier than finding an expert to optimize SQL Procedures.

Practical Implementation Guide

Before starting, check your MySQL version using the SELECT VERSION(); command. You need version 9.0 to run the examples below.

Step 1: Create Your First JavaScript Procedure

Test a simple procedure to verify the environment:

CREATE PROCEDURE hello_js(IN name TEXT) 
LANGUAGE JAVASCRIPT AS $$
  console.log("Hello " + name + ", JS is running in MySQL!");
$$;

Execute the command by calling it like a regular procedure:

CALL hello_js('Developers');

Step 2: Practical Business Logic Processing

Suppose you have a products table with a JSON details column. The task is to calculate the total inventory value for products with an “active” status.

CREATE PROCEDURE calculate_inventory_value(OUT total_value DOUBLE)
LANGUAGE JAVASCRIPT AS $$
  let results = session.sql("SELECT details FROM products").execute();
  let total = 0;
  
  results.fetchAll().forEach(row => {
    let details = JSON.parse(row[0]);
    if (details.status === 'active') {
      total += (details.price * details.stock);
    }
  });
  
  total_value = total;
$$;

The session.sql() object acts as a bridge. This coding style is very similar to using a DB driver in the backend, helping developers avoid context-switching overhead.

Real-world Experience: When to Apply It?

While JS is powerful, don’t turn your database into a “logic dumping ground.” Consider the following criteria:

Should be used when:

  • You need to process complex logic on large JSON datasets in-place.
  • Using mathematical operations or Regex that SQL handles poorly.
  • You want to encapsulate logic so multiple services (PHP, Go, Python) can share the same calculation result.

Should be avoided when:

  • Performing simple CRUD operations. Pure SQL remains the fastest choice.
  • The server is overloaded with CPU/RAM usage. Initializing the GraalVM engine consumes additional system resources.

Notes on Security and Performance

Security is the top priority. Never use string concatenation to avoid SQL Injection. Always use session.sql().bind() for safe parameter passing.

Regarding performance, I tested it on a table with 1 million records. Processing JSON with a JS Procedure was about 30% faster than using SQL’s JSON_EXTRACT function. Processing time dropped from 12 seconds to around 8.5 seconds, thanks to JS’s ability to optimize nested data structures.

The introduction of JavaScript in MySQL 9.0 helps bridge the gap between Database and Application code. If you’re starting a new project, try leveraging this feature to streamline your data processing engine.

Share: