diff --git a/pages/blog/posts/oracle-case-study.md b/pages/blog/posts/oracle-case-study.md index 9171e1afe..e3a85e2ce 100644 --- a/pages/blog/posts/oracle-case-study.md +++ b/pages/blog/posts/oracle-case-study.md @@ -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 @@ -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' -> ); -> ``` -> + 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' +); +``` + #### JSON Relational Duality View @@ -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). +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). #### POST method @@ -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. +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. ```sql -- Mark check constraints as PRECHECK @@ -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. +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. 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. @@ -1101,7 +1101,7 @@ Results: | {
  "firstName": "Bob",
  "address": "Paris",
  "vat": false
} |Paris|Bob|false|null| | {
  "firstName": "Bob",
  "address": "Paris",
  "vat": false,
  "tableEvolve": true
} |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. +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. ## Conclusion