Skip to content

Fix for PR1386 #1401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
24 changes: 12 additions & 12 deletions pages/blog/posts/oracle-case-study.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ tags:
- database
- relational
type: Case Study
cover: /img/posts/2025/oracle-case-study/blog_frontpage.webp
cover: /img/posts/2025/oracle-case-study/banner.webp
authors:
- name: Loïc Lefèvre
photo: /img/avatars/loiclefevre.webp
Expand Down Expand Up @@ -594,13 +594,13 @@ With all this in place, our React frontend can now create the following form:

![React frontend with input form generated from an annotated Oracle Database 23ai JSON schema.](/img/posts/2025/oracle-case-study/form.webp)

> Interestingly, whenever you change the schema annotation in the database, it is immediately reflected inside your browser once you refreshed it. You can try with:
> ```sql
> ALTER TABLE products MODIFY name ANNOTATIONS (
> REPLACE "title" 'Product name'
> );
> ```
>
<Infobox> Interestingly, whenever you change the schema annotation in the database, it is immediately reflected inside your browser once you refreshed it. You can try with:
```sql
ALTER TABLE products MODIFY name ANNOTATIONS (
REPLACE "title" 'Product name'
);
```
</Infobox>


#### JSON Relational Duality View
Expand Down Expand Up @@ -721,7 +721,7 @@ Running the 2 queries above respectively returns the data in JSON format:
|Wooden spatula|4.99|42|
|Other nice product|5|10|

> The `_metadata` object will contain additional information such as an `etag` that can be used for [optimistic concurrency control](https://docs.oracle.com/en/database/oracle/oracle-database/23/jsnvu/using-optimistic-concurrency-control-duality-views.html).
<Infobox>The `_metadata` object will contain additional information such as an `etag` that can be used for [optimistic concurrency control](https://docs.oracle.com/en/database/oracle/oracle-database/23/jsnvu/using-optimistic-concurrency-control-duality-views.html).</Infobox>

#### POST method

Expand Down Expand Up @@ -755,7 +755,7 @@ With 23ai, a check constraint can now be marked as [`PRECHECK`](https://docs.ora

Once a check constraint is marked as `PRECHECK`, you have the choice whether or not to disable the check constraint on the table as the retrieved JSON schema with `dbms_json_schema.describe()` will contain the check constraints as well.

> We do **NOT** advise to disable check constraints as it would allow inserting bad data into the relational tables directly. The remark about `PRECHECK` constraints is here to provide as much information as possible.
<Danger>We do **NOT** advise to disable check constraints as it would allow inserting bad data into the relational tables directly. The remark about `PRECHECK` constraints is here to provide as much information as possible.</Danger>

```sql
-- Mark check constraints as PRECHECK
Expand Down Expand Up @@ -1016,7 +1016,7 @@ select p.content.publishedDate.timestamp() + interval '5' day
from posts p;
```

> We use the item method `timestamp()` in the last statement above because otherwise the SQL dot notation would return a SQL `JSON` (by default in 23ai) on which we cannot apply an interval operation. However, because the value is already stored as `TIMESTAMP` inside the binary JSON format, there will be *no conversion* from `JSON` to `timestamp` here.
<Infobox>We use the item method `timestamp()` in the last statement above because otherwise the SQL dot notation would return a SQL `JSON` (by default in 23ai) on which we cannot apply an interval operation. However, because the value is already stored as `TIMESTAMP` inside the binary JSON format, there will be *no conversion* from `JSON` to `timestamp` here.</Infobox>

Last but not least, by enabling type casting, native SQL data type checks are also performed ensuring 100% fidelity between stored binary values in the encoded JSON and SQL data types. As a result, we can store not just the standard JSON data types but also the SQL data types inside the encoded binary JSON such as `NUMBER`, `DATE`, `TIMESTAMP`, `TIMESTAMP WITH TIME ZONE`, `INTERVAL`, `RAW`, `VECTOR`, etc.

Expand Down Expand Up @@ -1101,7 +1101,7 @@ Results:
| {<br/>&nbsp;&nbsp;"firstName": "Bob",<br/>&nbsp;&nbsp;"address": "Paris",<br/>&nbsp;&nbsp;"vat": false<br/>} |Paris|Bob|false|null|
| {<br/>&nbsp;&nbsp;"firstName": "Bob",<br/>&nbsp;&nbsp;"address": "Paris",<br/>&nbsp;&nbsp;"vat": false,<br/>&nbsp;&nbsp;"tableEvolve": true<br/>} |Paris|Bob|false|true|

> The trigger executes asynchronously, hence not delaying DML response times, however, because of it being asynchronous, it may take a second before you will see the new virtual column.
<Infobox>The trigger executes asynchronously, hence not delaying DML response times, however, because of it being asynchronous, it may take a second before you will see the new virtual column.</Infobox>

## Conclusion

Expand Down