# Natural-Language Calculations in APEX 26.2

## Introduction

I recently published a short post, [APEX AI Interactive Reports Just Got More Interesting](https://blog.cloudnueva.com/apex-ai-interactive-reports-just-got-more-interesting), on why natural-language computed columns in APEX 26.2 are a big deal. In this post I want to test this theory “users can create a new measure and then analyze it through the report using natural language alone”.

Interactive Reports already supported computations. APEX 26.2 adds the ability to describe the calculation in natural language and have AI create a standard report computation. The underlying SQL stays the same. [Oracle's 26.2 announcement](https://blogs.oracle.com/apex/whats-new-in-interactive-reports-and-ai-interactive-reports) explains the feature.

## Use case

For this example, we'll use a sales report for a fictional business selling hardware, software and services. The `CN_NL_SALES` table contains 300 sample sales lines covering January to September 2026. Each line includes the sale date, product category, product name, currency, revenue and cost. Revenue and cost are total amounts for the line.

Our starting report exposes revenue and cost. The sample also includes sales in USD, EUR and GBP, so we'll keep currencies separate when comparing monetary amounts. For the percentage calculation, we'll look at what happens when revenue is zero.

Imagine a sales manager using this report to understand which products are making money. The manager wants to see gross profit and gross margin, then use those measures to explore sales by product category.

## Environment and setup

These tests use APEX 26.2 and OpenAI's Luna model, `gpt-6-luna`, with reasoning effort set to `medium`.

To enable AI for the report, configure a Generative AI Service and associate it with the application. In Page Designer, select the Interactive Report region, open **Attributes → Generative AI**, enable **Natural Language Support**, and set **Default Search Mode** to **Search with AI**. These settings are visible in the Report Context screenshot below. [Oracle's setup guide](https://docs.oracle.com/en/database/oracle/apex/26.1/htmdb/adding-natural-language-support-to-interactive-reports.html) describes the configuration; the linked guide is for 26.1.

One interesting setup detail: AI Agents have a declarative Reasoning Effort setting:

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/8661cba0-bb67-47e5-8bda-052956bb4d83.png align="center")

I did not find an equivalent declarative setting on the AI Interactive Report (or even at the APEX app level). For these tests, I configured reasoning effort through **Additional Attributes** on the Generative AI Service, using the Responses API:

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/5da39552-59e8-43a7-a125-271fa03b8537.png align="center")

```json
{
  "reasoning": {
    "effort": "medium"
  }
}
```

This is the configuration used for these tests. Oracle also documents changing reasoning effort through an application's AI Request Handler. [APEX 26.2 release notes](https://docs.oracle.com/en/database/oracle/apex/26.2/htmrn/new-features.html).

## Prompts and Results

In this section I will go through three prompts that I used to test the new feature and discuss the results.

### Prompt 1: Add Gross Margin

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/3f5ae9bb-5424-40b5-91fa-1483653aa7df.png align="center")

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/00ce07b3-c3d7-4471-84d9-56543f6fb568.png align="center")

The calculation was correct, and it applied the correct formatting. Given this was a pretty vague prompt, I think this was a good result. The model interpreted “Gross Margin” as an amount: revenue minus cost.

The Compute dialog shows `F - G`. In this report, `F` is Revenue Amount and `G` is Cost Amount. For the first visible sale, 4,801.40 minus 3,360.98 gives the displayed result of 1,440.42.

### Prompt 2: Add Gross Margin %

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/20cb8f9a-2437-4a9a-bc5a-956fc4eb293e.png align="center")

The generated percentage calculation did not handle division by zero. A zero-revenue row caused `ORA-01476: divisor is equal to zero`, preventing the report from displaying.

I tried two ways to address this.

First, the user can include the requirement in the prompt:

> Add Gross Margin Percent and ensure division by zero is handled correctly

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/ad7fc03a-37fb-4563-8809-1f55be04947f.png align="center")

This worked in my test, but it is not ideal: we cannot rely on users to know that division by zero could be an issue. A better place for this guidance is the report's **Generative AI → Report Context** attribute. I added:

```text
When performing calculations make sure you handle divide by zero scenarios.
```

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/9afce508-d07b-4bc8-aa7b-aec1d8d85ff3.png align="center")

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/62683611-4d82-4259-a06f-8feaec4940db.png align="center")

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/ae82617d-c3c5-4959-95f0-a5322f61883a.png align="center")

With that Report Context instruction, the original percentage prompt produced this expression and an appropriate format mask:

```sql
CASE WHEN F = 0 THEN NULL
     ELSE ((F - G) / F) * 100
END
```

Again, `F` is revenue and `G` is cost. When revenue is zero, the percentage is undefined, so the expression returns `NULL`. Otherwise, it calculates gross profit as a percentage of revenue. A result of `40` represents 40%; the expression already includes the multiplication by 100.

> I think it would be a good idea for the APEX team to include division-by-zero protection in the generated code or the system prompt.

### Prompt 3: Show gross profit by product category for USD sales only

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/940df976-56bf-4726-a7a1-5fefb9340ad8.png align="center")

In this test, the first request created Gross Profit and filtered to USD, but did not complete the grouping. The assistant reported that the available report metadata did not expose the new column for grouping. That is a useful clue, but it does not establish the underlying cause or a general product limitation.

![](https://cdn.hashnode.com/uploads/covers/626b62127d5d27b992e4cf90/854a05fa-769a-46be-b638-dbf9d3249411.png align="center")

A second request, “add the group by,” produced the category totals I wanted. This supports the idea that users can analyze a newly calculated measure, although the extra request makes the experience less seamless than I expected.

> It is great that we can combine these functions, but completing the request in one shot would be easier for users.

## What does it all mean?

The useful part of this feature is what happens after we add the calculation. Our starting report had revenue and cost. We created Gross Profit, filtered to USD and then summed the new measure by product category. That is the part I wanted to demonstrate: giving users another way to answer their own questions about the data.

The results were encouraging, but they also showed where a little guidance makes a difference. “Add Gross Margin” produced a correct calculation with appropriate formatting. “Add Gross Margin %” exposed a divide-by-zero problem. Adding an instruction to the Report Context dealt with that case in my test. I think this guidance belongs with the report, where the developer can provide it once, rather than expecting every user to know which technical instructions to include.

The grouping example needed two requests: one to create the calculation and another to summarize it by category. The final result was useful, but the extra step is something users may need guidance with.

Of course, a result that looks right deserves a check. These examples show useful behavior with this dataset and these prompts. They also give us a reason to inspect the calculation, especially when the data includes missing values or a zero denominator.

## When the metric belongs in SQL

I see this as a useful tool for exploring data. If a user wants to try a calculation while investigating a question, being able to add it through a natural-language request is convenient. Once that calculation becomes a metric the business relies on, I would give it an agreed definition and implement it in SQL.

Gross margin is a good example. We need to agree whether we mean an amount or a percentage, what happens when revenue is zero, and how missing revenue or cost should be treated. We also need to keep currencies separate. These decisions matter just as much when a developer writes the calculation as when AI generates it.

There is another detail when we summarize the report: the average of the individual margin percentages is not necessarily the margin for the group. In our sample, the first two USD sales have margins of 40% and 20%. Their average is 30%, but their combined profit of $420 divided by combined revenue of $1,100 gives a margin of 38.18%. We need to decide which measure answers the business question.

For a shared metric, I would put the agreed logic in a view or the report's SQL source, test it, and give users clearly named columns. Defining the row calculation in SQL still leaves the aggregation rule to be agreed: a group margin needs matching revenue and cost inputs and the correct denominator. Users can then explore the data with those business definitions already in place.

## Conclusion

These tests reinforce why I think natural-language calculations are a useful addition to AI Interactive Reports. We created a measure that was missing from the source query and used it to answer a business question. It took a second request to get the category totals, and the percentage calculation needed guidance to handle zero revenue.

I would use this feature to help users explore their data, with clear Report Context and a check of the generated expression. When a calculation becomes a shared business metric, I would give it an agreed definition and implement it in SQL.

### Where is the Picture?

> The cover image is of the Swiss Alps overlooking Lake Lucerne, Switzerland.
