CREATE JSON RELATIONAL DUALITY VIEW

目的

JSONリレーショナル二面性ビューは、リレーショナル表のデータをJSONドキュメントとして公開します。ドキュメントはオンデマンドでマテリアライズされ、そのように格納されません。二面性ビューは関係的かつ階層的に編成されているため、概念と操作の二面性がデータに提供されます。1つ以上の同じ表に格納されているデータに基づいて異なる二面性ビューを作成し、同じ共有データに対して異なるJSON階層を提供できます。つまり、アプリケーションはJSONドキュメントのコレクションまたは関連表および列のセットと同じデータにアクセス(作成、問合せ、変更)でき、両方のアプローチを同時に使用できます。

主キー制約(PK)、外部キー制約(FK)または一意キー制約(UK)によって関連付けられた一連の表に対して、二面性ビューを定義します。以下のルールが適用されます。

  • 制約はデータベースで宣言する必要がありますが、強制する必要はありません(RELY DISABLE制約であってもかまいません)。

  • 関係タイプは、1対1、1対NおよびN対M (2つの外部キーを持つマッピング表を使用)のいずれかです。N対Mの関係は、1対Nと1対1の関係の組合せと考えることができます

  • UNNESTを使用して、1対1またはN対1の関係を持つ2つ以上の表の列を同じJSONオブジェクトにマージできます。それ以外の場合は、ネストされたJSONオブジェクトが作成されます。

  • 1対N関係を持つ表は、ネストされたJSON配列を作成します。

  • 二面性ビューには、JSON型の列が1つのみ含まれます。

  • 二面性ビューの各行は1つのJSONオブジェクトであり、これは通常、ネストされたオブジェクトと配列の階層です。

  • 各アプリケーション・オブジェクトは、そのビューの基礎となる表の1行または複数行からの値から構築されます。通常、各表は1つの(ネストされた) JSONオブジェクトに関与しています。

構文

create_json_relational_duality_view::=

object_gen_clause::=

key_value_clause::=

column_tags_clause::=

duality_view_subquery::=

table_tag_clause::=

graphql_query_for_DV::=

root_query_field_name::=

selection_list::=

query_field_name::=

query_scalar_field_name::=

query_object_field_name::=

fragment_spread::=

lower_case_name::=

name_continue_lower::=

scalar_field_name::=

object_field_name::=

object_field_name_lower::=

schema_name_lower::=

simple_object_type_name_lower::=

セマンティクス

JSONリレーショナル二面性ビュー(DV)には、JSONデータ型の列が1つのみ含まれます。列には、アプリケーション・オブジェクトを表すJSONオブジェクトが格納されています。列名は常にDATAです。

デフォルトでは、二面性ビューは読取り専用です。読取り専用は、NOINSERTNODELETENOUPDATEの注釈が有効であることを意味します。

OR REPLACE

OR REPLACEを指定すると、既存のビューを再作成できます。この句を使用した場合、以前に付与されたオブジェクト権限を削除、再作成、再付与しなくても、既存のビュー定義を変更できます。

IF NOT EXISTS

IF NOT EXISTSを指定すると、次の効果が得られます。

  • ビューが存在していない場合は、文の最後に新しいビューが作成されます。

  • ビューが存在している場合、これは文の最後の時点にあるビューになります。古いものが検出されるため、新しいものは作成されません。

単一の文には、一度に1つのOR REPLACEまたはIF NOT EXISTSしか指定できません。同じ文で両方を使用すると、次のエラーが発生します:

ORA-11541: REPLACEIF NOT EXISTSは同じDDL文で共存できません

IF EXISTSCREATEとともに使用すると、ORA-11543: 「CREATE文のIF NOT EXISTS句が正しくありません。」というエラーが発生します

table_tag_clause

WITH句内で次のキーワードを使用して、ビューを更新可能としてマークできます。

  • WITH INSERT

  • WITH UPDATE

  • WITH DELETE

キーワードをカンマで区切って組み合せることができます(例: WITH INSERT, UPDATE)。

column_tags_clause

個々の列をWITH UPDATEまたはWITH NOUPDATEでマークできます。これは、表レベルの注釈に優先します。

更新可能性の列プロパティ

そのようなキーワードでFROM句がマークされている場合は、FROM句内の表のすべての列に対してデフォルトが設定されます。個々の列でデフォルト設定を変更できます。FROM句がWITH (INSERT, UPDATE, DELETE)として指定されており、列がこのデフォルトをNOUPDATEでオーバーライドする場合、更新は許可されません。

ETAGの列プロパティ

個々の列およびFROM句を、CHECK ETAG計算に参加するように、または参加しないように指定できます。ETAGは、1つのJSONオブジェクト内のすべての列値のハッシュ値であり、変更の検出に使用されます。ETAGのない列は、その変更が他の操作に影響を与えることなく変更できます。デフォルトでは、すべての列がETAG計算に参加します。NOCHECK ETAGを使用すると、ETAG計算から列を除外できます。

graphql_query_for DV

graphql_query_for_DVは、GraphQLの特殊な短縮問合せ操作定義です。

  • root_query_fieldは、この短縮問合せの単一のトップレベルの選択フィールドです。

    簡潔にするために、graphql_query_for_dvでは、一般的な短縮問合せ操作のトップレベルのselection_setの中カッコのペアが省略されます。

  • selection_set構文では、オプションの大カッコで選択リストを囲むというオプションを使用して、GraphQL仕様で定義された選択セットが拡張されます。
  • selection_listselectionには、fieldまたはfragment_spreadのみを指定できます。

  • field directives: GraphQL仕様に準拠します。サポートされているカスタム・ディレクティブのみが許可されます。@skipおよび@includeはサポートされていません。

  • argumentは、GraphQL仕様に準拠します。

  • root_query_field_nameは、ルート表に対応します。

  • nameの構文は、GraphQL仕様と同じです。

  • quoted_name: DVに対するGraphQL問合せのフィールド名では、引用符付きの名前と引用符なしの名前が許可されます。慣例として、引用符なしのフィールド名は小文字のみになります。any_charは、SQLの引用符付き識別子で許可される任意の文字です。

  • scalar_field_nameは、表の列名に対応します。

  • object_field_nameは、関連する表名に対応します。また、引用符付きの名前と、ドット連結で指定された完全修飾表名を使用することもできます。

関連項目:

例1: オーダーの二面性ビューの作成

次の例は、次の情報が含まれるオーダー・ビュー・オブジェクトORDERS_OVのビューです。

  • Orders表のオーダー・ステータスなどのオーダー情報

  • Customer表の顧客詳細で構成されるCustomerInfoシングルトンの子孫

  • OrderItems表のオーダー品目のリストで構成されるOrderItems配列の子孫。

  • 各オーダー品目は、それぞれProducts表とShipment表のItemInfoシングルトンとShipmentInfoシングルトンで構成されます。

CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW ORDERS_OV AS
SELECT JSON { 'OrderId'   : ord.order_id, 
              'OrderTime' : ord.order_datetime,
	        'OrderStatus' : ord.order_status,
              'CustomerInfo' : 
			  (SELECT JSON{'CustomerId'    : cust.customer_id,
	    	                      'CustomerName'  : cust.full_name,
                                  'CustomerEmail' : cust.email_address }	                                                                         
			   FROM CUSTOMERS cust 
                     WHERE cust.customer_id = ord.customer_id),	
              'OrderItems' : (SELECT JSON_ARRAYAGG(
					JSON { 'OrderItemId' : oi.line_item_id,
                                       'Quantity'    : oi.quantity, 					  			
                                       'ProductInfo' : <subquery from product>        
                                	 'ShipmentInfo' : <subquery from shipments>)                                                                                           
                            }) 
                            FROM ORDER_ITEMS oi		
                            WHERE ord.order_id = oi.order_id) 
}
FROM ORDERS ord;

例2: 更新可能なビューの作成

ビューを更新可能にするには、INSERTUPDATEまたはDELETE、あるいはこれらの組合せをFROM句または個々の列に追加する必要があります。次の例では、オーダーの更新、顧客の読取りのみ、オーダー品目の挿入および更新(削除以外)を許可します。

CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW ORDERS_OV AS
SELECT JSON { 'OrderId'     : ord.order_id, 
              'OrderTime'.  : ord.order_datetime,
	         'OrderStatus' : ord.order_status,
              'CustomerInfo' : 
		     (SELECT JSON{'CustomerId'    : cust.customer_id,
	    	                  'CustomerName'  : cust.full_name,
                             'CustomerEmail' : cust.email_address WITH NOCHECK}	                                                                         
			   FROM CUSTOMERS c WITH CHECK
                     WHERE cust.customer_id = ord.customer_id),	
              'OrderItems' : (SELECT JSON_ARRAYAGG(
					JSON { 'OrderItemId' : oi.line_item_id,
                                       'Quantity'    : oi.quantity, 
                                       'ProductInfo' : <subquery from product>     
                                       'ShipmentInfo' : <subquery from shipments>)                                                                                           
                            }) 
                            FROM ORDER_ITEMS oi WITH INSERT, UPDATE		
                            WHERE ord.order_id = oi.order_id) 
}
FROM ORDERS ord WITH INSERT, UPDATE, DELETE;