Skip to Content
Author's profile photo Sawa Ito

SAP SQL Anywhere 16.0.1823 における OData サポートの強化

このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。

 

 

 

紹介

 

2013年3月のSQL Anywhere 16.0 のリリースにおいて、ODataプロトコルのサポートが紹介されました。これにより、追加のコードを作成したりデータベースオブジェクトを作成することなく、データソースからのWebサービスへの容易なアクセスが可能になりました。これについては、 こちらのブログ記事に記載しました。こちらのブログ記事は、新しいOData サーバーのアーキテクチャーの基本をカバーし、ステップバイステップでSQL Anywhere 16 に含まれているODataのサンプルをどのように使用するか解説しています。

 

このブログ記事では、SQL Anywhere 16 ビルド#1823に実装された特定の新機能セットについてカバーします。ライセンスをお持ちで有効なサポート契約を締結されているお客様は、このビルド番号のものをSAP Support Portal よりダウンロードしていただくことが可能です。

 

背景

 

SQL Anywhere 16 OData サーバーの最初のリリースは、とても簡単にセットアップして使用できるものでした。しかしながら、機能に制限のあるいくつかのデフォルトの動きがありました。

 

  1. 一つのテーブル内に、定義されたプライマリキーがあると、自動的にODataエンティティとして公開することができました。しかしこのデフォルトの動きは、そのテーブル内の全てのカラムを公開してしまいました。テーブル内のカラムのサブセットを公開する簡単な方法はありませんでした。
  2. OData エンティティ名は、マッチングするテーブルおよびビューの名前から設定されました。OData エンティティに異なる名前を使用する方法はありませんでした。
  3. ビューは、.OSDL 設定ファイルの中にリストすることで、ODataのエンティティとして公開するしかありませんでした。ビューをリストするには、ビューの「プライマリキー」として使用される1つまたはそれ以上のカラムを選択し、keys() 文の中にリストする必要がありました。
  4. そのデータベースに二つのテーブル間を定義する外部キーがある場合、SQL Anywhere 16 では自動的に2つのエンティティ間にOData 「関連付け」を作成しました。定義された外部キーがない2つのテーブル間またはビュー間で関連付けを作成する機能はありませんでした。
  5. 2つのエンティティ間の関連付けをしていたカラムは、依存するエンティティの定義には現れませんでした。言いかえると、OrdersとOrder_Items が「order_id」カラムで関連付けられている場合、それがOrder_Items テーブル内のカラムであっても「order_id」は「Order_Items」エンティティの定義にはプロパティとしては現れませんでした。
  6. インプットパラメーターをとるデータベースのストアドプロシージャを呼び出すの機能がありませんでした。パラメーターのないプロシージャは、それらをビューとしてラッピングし、.OSDLファイル内のビューを公開することで、ODataエンティティとして公開されました。

 

良いニュースは、これらの問題は全てビルド#1823 で解決されたということです。これらの新しい機能を解説するために、 このブログで作成したNorthwind サンプルデータベースを使用します。このブログを参照して、添付のZIP ファイルをダウンロードしてください。

 

OSDL ファイルの変更

 

.OSDL ファイル言語には、3つのタイプの文があります。 ENTITY、ASSOCIATION、そして SERVICEOP です。  それぞれ別に説明します。

 

ENTITY 定義

 

  1. 構文     entity “owner“.”object-name[ as “entityset-name]         [ { with | without } (“included-or-excluded-column- name[ , … ]) ]         [ keys ( { (“key-column-name[ , … ]) | generate local “key-column-name} ]   

            [ concurrencytoken (“token-column-name[ , … ] ) ]
    [
    navigates (“association-name” as “navprop-name[ from { principal | dependent } ] [, …] ) ]

  • asentityset-name”‘  これによりエンティティのOData 定義内のマッチングテーブルまたはビューとは異なる名前を使用することができます。
  • { with | without } (“included-or-excluded-column-name“[, …])  OData定義内の包括的なカラムリストを作成するには、 WITH と、コンマで分けられたカラム名リストを使用します。排他的なリスト(例:これらリストされているものを除いた全カラム)を作成するには、WITHOUT キーワードを使用します。
  • keys ( { (“key-column-name”[, …])  これは、定義されたプライマリキーがないテーブルまたはビューにのみ必要です。generate local key-column-name” 文は、Edm.Int64 タイプの生成されたプロパティタイプを結果においてユニークなIDとして使用する結果セットに追加します。使用される場合には、これらは1から順にナンバリングされ、現在の検索にのみ有効です。
  • concurrencytoken (“token-column-name” [, …])  これは、例えば、DEFAULT CURRENT TIMESTAMP や、更新トリガーによって増加するインテジャーカラムエンティティのインスタンスが更新される時はいつも修正されるカラム (‘properties’) のリストです。
  • navigates (“association-name”asnavprop-name” [ from { principal | dependent }  この文は、「Association」オブジェクトを参照することで2番目のエンティティに対してのassotiation を定義します。これは、次のセクションでより明確に解説します。…

 

ASSOCIATION 定義

 

基礎にあるテーブルを含む複雑な association を含め、エンティティ間の association を作成します。これらは、2つのデータベーステーブル間に物理的な外部キーの定義が存在しない時のみ必要です。

 

構文

    associationassociation-name”

                  principal principal-entityset-name” (“column-name” [, …]) multiplicity [ 1 | 0…1 | 1..* | * ]

                dependentdependent-entityset-name” (“column-name” [, …]) multiplicity “[ 1 | 0..1 | 1..* | *]

                  over “owner”.”object-name” principal (“column-name” [, …]) dependent (“column-name” [, …])

 

  • association-name  association 用の名前 – 名前スペース内でユニークでなければならない。この名前は、その Entity navigates 文内で参照されます。
  • principal  ここで提供される名前は、assotiation の「parent」サイドで、その Entity navigates 文の中で、navprop-name プロパティとして参照されます。
  • dependent  ここで提供される名前は、association の「child」サイドです。
  • multiplicity  “1” = 必ず 1:1 の関係;  “0..1” = オプショナルの 1:1 の関係; “1..*” = 必ず 1:m の関係; “*” = オプショナルの 1:m の関係
  • over  この文は、物理的なデータベーステーブルが関連するテーブルとして使用され、プリンシパルと依存するエンティティの両方のプライマリキーが含まれるの時のみ使用します。 

 

SERVICEOP 定義

 

データベースストアドプロシージャーまたは関数を HTTP GET または POST オペレーションとして公開します。

 

構文

    serviceop { get | post } catalog-object-name

        [ as service-name ]

        [ returns multiplicity “{ 0 | 1 | * }”

 

  • get | post    HTTP GET または POSTとしてサービスを作成します。同じデータベースのオペレーションを GET と POST の両方として公開することができますが、ユニークなサービス名で作成する必要があります。catalog-object-name は、呼び出すデータベースストアドプロシージャーまたは構文を参照します。The OData サーバーは、自動的に入力パラメーターを懐石し、それらを $metadata内の IN パラメーターとして作成します。
  • returns multiplicity
    • オペレーションにアウトプットがない場合は「0」を使用します;
    • オペレーションが単一のスカラー値または単一の複雑なタイプを返す場合には「1」を使用します。
    • オペレーションがシンプルまたは複雑なタイプの集合を返す場合には、 「*」を使用します。

 

 

 

上にリストした機能のいくつかの例をみてみます。 (以下の .OSDL ファイルへの全ての変更は、DBOSRV16 プロセスの再起動が必要です。)

 

Entity 定義からカラムを除く

 

OData サーバーは、デフォルトでは、テーブル内の全てのカラムをOData プロパティとして公開します。BirthDate と HireDate カラムを Employee エンティティから除きます。

 

.OSDL ファイルを編集して、Employee エンティティのエンティティ定義を見つけます。プライマリキーがあるので、単に:

  1. “DBA”.“Employees” ;

このラインを変更して:

  1. entity “DBA”.“Employees” without (“BirthDate”, “HireDate”);

ブラウザを開き、以下にナビゲートすると

BirthDate と HireDate がエンティティ定義から取り除かれていることがわかります。

 

 

テーブルとビューの間にAssociationを作成する

 

「Sales_by_Category」 というOData エンティティ(と同じ名前のビュー) は、製品カテゴリ内で製品毎の合計売上をまとめます。とても良い機能が、ベースとなるCategories エンティティをこのビューに関連付けして、単一のOData クエリで両方のデータセットを返すことができることです。これは、OSDL ファイルにAssociation エントリーを作成し、二つのEntity 文をそのAssociation にリンクすることでできます。

 

Northwind.OSDL ファイルを編集して、以下のラインをファイルのボトムに追加します:

  1. association “CategorySales”
  2.   principal “Categories” (“CategoryID”) multiplicity “1”
  3.   dependent “Sales_by_Category” (“CategoryID”) multiplicity “*” ;

Categories エンティティの Entity エントリーを以下に変更します:

  1. entity “DBA”.“Categories”
  2.       navigates (“CategorySales” as “Sales_by_Category”);

Sales_by_Category エンティティのEntity エントリーを以下に変更します:

  1. entity “DBA”.“Sales_by_Category” keys(“CategoryID”,“ProductName”)
  2.   navigates (“CategorySales” as “Categories”);

OData サーバーの再起動後、ブラウザを開き

各Category 内で、製品毎に売上合計が分かれていることを確認できます。

 

 

OData サービスのオペレーションを呼び出す

 

ストアドプロシージャを呼び出し、引数にパスすることがSQL Anywhere 16 では可能になりました。Northwind.OSDL ファイルを編集して、以下のラインをボトムに追加します:

  1. serviceop get “dba”.“salesbycategory” returns multiplicity “*” ;

“dba”.”salesbycategory” というストアドプロシージャは、@CategoryName と @OrdYear という2つの構文をとり、結果セットを返します。上で記載した ServiceOP 文は、input 引数または結果セットの構造体でもないことに注意してください。OData サーバーは自動的にそのプロシージャーを解析し、これらを $metadata ドキュメントに追加します。引数は、URLにパラメーターとしてパスされます。

 

ブラウザを開き

プロシージャーの呼び出しの結果を確認します。いくつかの注意点があります:

  1. OData サーバーはフィールド名を決定する結果セットを解析しないようです。名前は、「rtn1」から順に生成されます。
  2. パラメーター名は、大文字小文字を区別します。
  3. 関数パラメーターには、single-quotes が必要です。

 

 

-Paul Horan-

 
===

 

SAP SQL Anywhere に関する詳細情報は、SAP SQL Anywhere Communityページ<英語> を参照してください。

 

上記のコミュニティーに掲載されている技術情報は、順次SQL Anywhere 日本語コミュニティ

に掲載しています。

 

SQL Anywhere に関してはまずはこちらをご参照ください。無期限でご利用いただける無償の Developers Edition もこちらからダウンロードが可能です。

 

SQL Anywhere に関して技術的な質問のある方はコミュニティに登録し、
「Ask a Question」機能をご利用ください。

Language には「Japanese」、
Primary Tag には「SAP SQL Anywhere」を選択
User Tagに「sql anywhere」「sql anywhere Japanese question」

を入力してください。

不具合につきましては、サポート契約者様専用の問い合わせ方法にてお問い合わせください。

 

======================
ご購入に関するお問い合わせ

こちらよりお問い合わせください。

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.