3.3 WHERE Clauses in Duality-View Tables

When creating a JSON-relational duality view, you can use simple tests in WHERE clauses to not only join underlying tables but to select which table rows are used to generate JSON data. This allows fine-grained control of the data to be included in a JSON document supported by a duality view.

As one use case, you can create multiple duality views whose supported JSON documents contain different data, depending on values in discriminating table columns.

For example, using the same underlying table, ORDERS, of purchase orders you could define duality views open_orders and shipped_orders, with the first view selecting rows with clause WHERE order_status="open" from the table and the second view selecting rows with WHERE order_status="shipped".

But note that columns used in the test of a WHERE clause in a duality view need not be used to populate any fields of the supported JSON documents. For example, the selected purchase-order documents for views open_orders and shipped_orders need not have any fields that use values of column order_status.

Each WHERE clause used in a duality-view definition must contain the keywords WITH CHECK OPTION. This prohibits any changes to the table that would produce rows that are not included by the WHERE clause test. See CREATE VIEW in Oracle Database SQL Language Reference.

The WHERE clauses you can use in duality-view definitions must be relatively simple — only the following constructs can be used:

  • Direct comparison of column values with values of other columns of the same underlying table, or with literal values. For example, height > width, height > 3.14. Only ANSI SQL comparison operators are allowed: =, <>, <, <=, >, >=.

  • A (non-aggregation) SQL expression using a column value, or a Boolean combination of such expressions. For example, upper(department) = 'SALES', salary < 100 and bonus < 15.

  • Use of SQL JSON constructs: functions and conditions such as json_value and json_exists, as well as simple dot-notation SQL syntax.

In particular, a WHERE clause in a duality-view definition cannot contain the following (otherwise, an error is raised).

  • Use of a PL/SQL subprogram.

  • Comparison with the result of a subquery. For example, t.salary > (SELECT max_sal FROM max_sal_table WHERE jobcode=t.job).

  • Reference to a column in an outer query block.

  • Use of a bind variable. For example, salary = :var1.

  • Use of an aggregation operator. For example, sum(salary) < 100.

  • Use of multiple-column operations. For example, salary + bonus < 10000.

  • Use of OR between a join condition and another test, in a subquery. Such use would make the join condition optional. For example, e.deptno=d.deptno OR e.job='MANAGER' — in this case, e.deptno=d.deptno is the join condition. (However, OR can be used this way in the top-level/outermost query.)

Example 3-9 WHERE Clause Use in Duality View Definition (SQL)

This example defines duality view race_dv_medal, which is similar to view race_dv (Example 3-5). It differs in that (1) it uses an additional WHERE-clause test to limit field result to the first three race positions (first, second, and third place) and (2) it includes only races more recent than 2019.

CREATE JSON RELATIONAL DUALITY VIEW race_dv_medal AS
  SELECT JSON {'_id'    : r.race_id,
               'name'   : r.name,
               'laps'   : r.laps WITH NOUPDATE,
               'date'   : r.race_date,
               'podium' : r.podium WITH NOCHECK,
               'result' :
                 [ SELECT JSON {'driverRaceMapId' : drm.driver_race_map_id,
                                'position'        : drm.position,
                                UNNEST
                                  (SELECT JSON {'driverId' : d.driver_id,
                                                'name'     : d.name}
                                     FROM driver d WITH NOINSERT UPDATE NODELETE
                                     WHERE d.driver_id = drm.driver_id)}
                     FROM driver_race_map drm WITH INSERT UPDATE DELETE
                     WHERE drm.race_id = r.race_id
                           AND drm.position <= 3 WITH CHECK OPTION ]}
    FROM race r WITH INSERT UPDATE DELETE
    WHERE r.race_date >= to_date('01-JAN-2020') WITH CHECK OPTION;

Example 3-10 WHERE Clause Use in Duality View Definition (GraphQL)

This example defines duality view race_dv_medal using GraphQL. It is equivalent to creating the view using SQL as in Example 3-9.

The view is similar to view race_dv (Example 3-8). It differs in that (1) it uses an additional WHERE-clause test to limit field result to the first three race positions (first, second, and third place) and (2) it includes only races more recent than 2019.

CREATE JSON RELATIONAL DUALITY VIEW race_dv_medal AS
  race @insert @update @delete
       @where (sql: "race_date >= to_date('01-JAN-2020')")
  {_id    : race_id,
   name   : name,
   laps   : laps @noupdate,
   date   : race_date,
   podium : podium @nocheck,
   result : driver_race_map @insert @update @delete
                            @where (sql: "position <= 3")
     {driverRaceMapId : driver_race_map_id,
      position        : position,
      driver @noupdate @nodelete @noinsert
        @unnest
        {driverId : driver_id,
         name     : name}}};