11 プロシージャ、変数、順序およびユーザー関数の作成および使用

この章では、プロシージャ、変数、順序およびユーザー関数の使用方法について説明します。これらのコンポーネントの概要についても説明します。

この章の内容は次のとおりです。

11.1 プロシージャの使用

この項では、プロシージャの概要について説明し、Oracle Data Integratorでプロシージャを作成および使用する方法について説明します。

次の各項では、プロシージャを作成および使用する方法について説明します。

11.1.1 プロシージャの概要

プロシージャは、エージェントが実行できる一連のコマンドです。これらのコマンドは、Oracle Data Integratorでアクセスできるすべてのテクノロジ(OS、JDBC、JMSコマンドなど)に関係しています。

プロシージャは、マッピング・フレームワークに適応しないアクションをグループ化できる、再利用可能なコンポーネントです。プロシージャの使用は、必要な作業がマッピングで実現できない場合のみ検討してください。その場合は、外部プログラムやスクリプトを記述するのではなく、Oracle Data Integratorにコードを挿入し、パッケージからそのコードを実行します。マッピングとは対象的に、プロシージャを使用する場合はすべてのコードを手動で開発する必要があります。

プロシージャは、プロパティを持つタスクで構成されます。各タスクには、ソースに対するコマンドとターゲットに対するコマンドの2つがあります。これらのコマンドはスクリプトで、異なる言語が混在していることもあります。タスクは順番に実行されます。オプションで制御されているコマンドはスキップできる場合があります。これらのオプションによって、コマンドをコマンドのコードと同様に実行するかどうかがパラメータ化されます。

プロシージャ内のコードは、オプションおよびODI置換APIを使用して汎用化できます。

プロシージャを作成する前に、次の点に注意してください。

  • プロシージャでデータ変換を実行することは可能ですが、この目的でのプロシージャの使用はお薦めできません。かわりに、マッピングを使用してください。

  • データ操作用に特定の繰返しタスクを自動化するには、複雑なプロシージャを記述するよりも、そのタスクをナレッジ・モジュールに変換することを検討してください。詳細は、『Oracle Data Integratorでのナレッジ・モジュールの開発』を参照してください。

  • オペレーティング・システム固有のコマンドはできるだけ使用しないでください。このようなコマンドを使用すると、コードはエージェントを実行しているオペレーティング・システムに依存します。2つの異なるオペレーティング・システム(UNIXとWindowsなど)でエージェントが同じプロシージャを実行すると、適切に動作しません。

11.1.2 プロシージャの作成

プロシージャは標準プロセスに従って作成しますが、ユース・ケースによって異なる場合があります。次のステップは、プロシージャの作成に際して一般的に実行するステップです。

  1. 新規プロシージャの作成

  2. プロシージャのオプションの定義

  3. プロシージャのタスクの作成および管理

プロシージャを作成するときは、次のコーディング・ガイドラインを理解することが重要です。

11.1.2.1 新規プロシージャの作成

新規プロシージャを作成するには:

  1. デザイナ・ナビゲータで、プロシージャを作成するプロジェクトのフォルダ内にある「プロシージャ」ノードを選択します。
  2. 右クリックして「新規プロシージャ」を選択します。
  3. 「定義」タブで、プロシージャの「名前」を入力します。
  4. プロシージャで同時に複数の接続を管理する場合は、「複数接続」を選択します。

    複数接続: あるソース接続に送信されたコマンドによって取得されたデータを、別の(ターゲット)接続に送信されたコマンドで使用する場合は、複数接続プロシージャを選択すると便利です。このデータは、実行エージェントを介して渡されます。「複数接続」を有効にすると、「タスク」の「ターゲット」フィールドと「ソース」フィールドの両方を使用できます(「プロシージャのタスクの作成および管理」を参照)。

    一度に1つの接続にアクセスする場合(別の接続にもアクセスできますが、一度に1つの接続のみにアクセスする場合)、「複数接続」ボックスは選択しないままにします。ターゲット・タスクのみ使用されます。

  5. 「ターゲット・テクノロジ」を選択します。「複数接続」ボックスを選択した場合は「ソース・テクノロジ」も選択します。新規の各プロシージャ行は、このテクノロジに基づいています。これらのフィールドを空のままにして、各プロシージャ・コマンドにテクノロジを指定することもできます。

    警告:

    プロシージャを保存する際に、ソース・テクノロジとターゲット・テクノロジの選択は必須ではありません。ただし、関連するコマンドを特定のテクノロジや論理スキーマに関連付ける必要がある場合は、プロシージャの実行に失敗する可能性があります。

  6. オプションで、「一意の一時オブジェクト名を使用」および「エラー時に一時オブジェクトを削除」を選択します。
    • 一意の一時オブジェクト名を使用: このプロシージャを同時に実行できる場合は、このオプションを有効にして、競合しない一時オブジェクト名を作成します。

    • エラー時に一時オブジェクトを削除: セッションでエラーが発生してもクリーン・アップ・タスクを実行するには、このオプションを有効にします。

  7. オプションで、このプロシージャの説明を入力します。
  8. 「ファイル」メニューから「保存」をクリックします。

新規プロシージャが作成され、プロジェクトのツリーにある「プロシージャ」リストに表示されます。

11.1.2.2 プロシージャのオプションの定義

プロシージャのオプションは、タスクでパラメータと同様に機能し、コードの再利用性が向上します。

次の3つのタイプのオプションがあります。

  • ブール・オプション。この値を使用すると、コマンドを実行するかどうかを個別に決定できます。このオプションは、if文と同じように機能します。

  • 「値」オプションは短いテキスト情報を渡す場合に使用し、「テキスト」オプションは長いテキスト情報を渡す場合に使用します。これらのオプションの値は、getOption()置換メソッドを使用してプロシージャのコマンドのコード内でのみリカバリできます。パッケージでプロシージャを使用する場合、その値はステップの中で設定できます。

プロシージャのオプションを作成するには:

  1. デザイナ・ナビゲータで、構成するプロシージャをダブルクリックします。プロシージャ・エディタが開きます。
  2. 「オプション」タブを選択します。「オプション」表で、「追加オプション」ボタンをクリックして表に行を追加します。各行は1つのオプションを表します。
  3. オプションの次のフィールドを編集します。
    • 名前: グラフィカル・インタフェースに表示されるオプションの名前。

    • タイプ: オプションのタイプ。

      • ブール: オプションはブールです(True = 1/False = 0)。これはプロシージャとKMでのみ使用され、タスクの実行が必要かどうかを決定するオプションです。

      • テキスト: 英数字型のオプション。サイズは無制限です。このタイプのオプションへのアクセスは、値オプションより低速です。

      • : 英数字型のオプション。最大250文字です。

    • デフォルト値: プロシージャまたはKMのユーザーが値を指定しなかった場合にオプションに設定される値。

    • 直接実行値: 様々なオプション値でプロシージャを実行またはテストする場合に使用します。直接実行値のデフォルトは、このオプションの対応するデフォルト値です。デフォルト値は上書きできます。上書きすると、直接実行値に新しいデフォルト値が設定されます(前に変更されていない場合)。オプションの「直接実行値をデフォルトにリセット」コンテキスト・メニュー項目を使用すると、値がデフォルト値にリセットされます。

    • 説明: オプションの短い説明(省略可)。ブール・オプションの場合、「タスク」表の行を選択すると、「プロパティ・インスペクタ」の「オプション」タブにこの説明が表示されます。

    • ヘルプ: オプションに関する使用上の説明(省略可)。プロシージャの場合、マッピングでプロシージャを選択すると、プロパティ・ペインにこのテキストが表示されます。

    ノート:

    コンテキスト・メニューを表示するには、オプションを右クリックします。このメニューから、オプションを複製したり、直接実行値をデフォルトにリセットできます。

  4. 複数のオプションがある場合は、表で順序を設定します。行を選択し、メニュー・バーの上下のボタンを使用してリスト内の位置を変更します。オプションは上から下に順番にチェックされます。
  5. プロシージャに必要なオプションごとにこれらの操作を繰り返します。
  6. 「ファイル」メニューから「保存」をクリックします。
11.1.2.3 プロシージャのタスクの作成および管理

ほとんどのプロシージャは、ターゲットでのみコマンドを実行します。場合によっては、プロシージャに、データの読取りとこのデータを使用したアクションの実行が必要になることがあります。このような場合、「ソース」フィールドでデータを読み取るコマンドを指定し、「タスク」タブの「ターゲット」フィールドでそのデータを使用して実行するアクションを指定します。詳細は、「ソース・データとターゲット・データのバインド」を参照してください。ソース・データストアに対してコマンドを実行しない場合は、「ソース」フィールドを空白のままにすることができます。

次のオプションを使用して、プロシージャのタスクを作成および管理します。

プロシージャのタスクの作成

  1. デザイナ・ナビゲータで、コマンドを作成するプロシージャをダブルクリックします。プロシージャ・エディタが開きます。

  2. プロシージャ・エディタで、「タスク」タブに移動します。プロシージャにすでにあるタスクが表にリストされます。

  3. 「追加」をクリックします。新しいタスク行が表に作成されます。行のフィールドを編集してタスクを構成します。

    使用可能なフィールドは次のとおりです。

    ノート:

    • フィールドが表示されない場合は、「列の選択」ボタンを使用して表の非表示列を表示します。または、プロパティ・インスペクタを開き、タスク行を選択してプロパティ・インスペクタに次のフィールドの一部を表示します。「常に実行」オプションは、プロパティ・インスペクタにのみ表示されます。

    • 「トランザクション」、「コミット」および「トランザクション分離」オプションは、トランザクションをサポートするテクノロジでのみ機能します。

    • 名前: このタスクの名前を入力します。

    • クリーンアップ: プロシージャでエラーが発生してもタスクを実行する場合は、タスクをクリーンアップ・タスクとしてマークします。たとえば、一時オブジェクトを削除するにはクリーンアップ・タスクを使用します。

    • エラーの無視: コマンドがエラーを戻してもプロシージャを停止しない場合は、選択する必要があります。このボックスを選択すると、プロシージャ・コマンドによってエラーではなく警告メッセージが生成され、プロシージャは停止しません。

    • ソース・トランザクション/ターゲット・トランザクション: コマンドを実行するトランザクション。

      「トランザクション」および「コミット」オプションを使用すると、コマンドをトランザクション内で実行できます。詳細は、「RDBMSトランザクションの処理」を参照してください。

    • ソースのコミット/ターゲット・コミット: トランザクションのコマンドのコミット・モードを指定します。

      「トランザクション」および「コミット」オプションを使用すると、コマンドをトランザクション内で実行できます。詳細は、「RDBMSトランザクションの処理」を参照してください。

    • ソース・テクノロジ/ターゲット・テクノロジ: このコマンドのテクノロジ。設定しないと、プロシージャ・エディタで指定されているテクノロジが使用されます。

    • ソース・コマンド/ターゲット・コマンド: 実行するコマンドのテキスト。コマンド・フィールドの「...」をクリックして式エディタを開くことができます。

      コマンドは、選択したテクノロジに適した言語で入力する必要があります。詳細は、「プロシージャのコードの記述」を参照してください。

      置換メソッドを使用してコードを汎用化し、トポロジ情報に依存することをお薦めします。置換APIの使用を参照してください。

    • ソース・コンテキスト/ターゲット・コンテキスト: 実行の強制コンテキスト。未定義のままにすると、実行コンテキストが使用されます。任意のコンテキストにコードを移植できるようにするには、未定義のままにします。

    • ソース論理スキーマ/ターゲット論理スキーマ: コマンド実行用の論理スキーマ。

    • ソース・トランザクション分離/ターゲット・トランザクション分離: コマンドのトランザクション分離レベル。

    • ログ・カウンタ: このコマンドで処理される行の数を記録するカウンタ(「挿入」、「更新」、「削除」または「エラー」)を示します。ログ・カウンタは、InsertまたはUpdate SQL文で戻される挿入、更新、削除およびエラーの行に対してのみ機能することに注意してください。

      ヒント:

      プロシージャを実行した後は、オペレータ・ナビゲータにカウンタの結果を表示できます。この結果は、ステップまたはタスクのエディタの「定義」タブにある「レコード統計」セクションに表示されます。

    • ログ・レベル: コマンドのログ・レベル。実行時に、このコマンドに生成されたタスクは、この値および実行パラメータに定義されたログ・レベルに基づいてセッション・ログに記録されます。実行パラメータの詳細は、『Oracle Data Integratorの管理』実行パラメータの表を参照してください。

    • ログの最終コマンド: ODI実行ログでは、通常、最終タスクのコード処理の前にタスク・コードが書き出されます。このフラグは、事前に処理されたコマンドに加えて最後に処理されたコマンドをログに記録する場合に有効にします。

    • オプション: プロパティ・インスペクタの「オプション」ノードは、使用可能なすべてのオプションがリストされた表です。これらのオプションは、プロパティ・インスペクタにのみ表示されます。

      • 常に実行: 他のオプション値に関係なく常にこのコマンドを実行する場合は、これを有効にします。

      • 他のオプションは表にリストされています。使用可能なオプションは、プロシージャによって異なります。「常に実行」を選択しなかった場合は、選択したタスクに対して実行する個別のオプションを選択できます。

      ノート:

      これらのオプションは、プロパティ・インスペクタにのみ表示されます。タスク・オプションを表示するには、タスク行を選択してからプロパティ・インスペクタで「オプション」タブを選択します。

  4. 「ファイル」メニューから「保存」を選択します。

タスク・リストの既存タスクのコピーを作成できます。

タスクの複製

  1. プロシージャの「タスク」タブに移動します。

  2. 複製するコマンドを選択します。

  3. 右クリックして「複製」を選択します。新規の行がタスクのリストに追加されます。選択したコマンドのコピーが表示されます。

  4. 必要な変更を加えて、「ファイル」メニューから「保存」をクリックします。

リストからタスクを削除できます。

タスクの削除

  1. プロシージャの「タスク」タブに移動します。

  2. 削除するコマンド行を選択します。

  3. エディタ・ツールバーで「削除」をクリックするか、行を右クリックしてコンテキスト・メニューから「削除」を選択します。

コマンド行がリストから削除されます。

タスクが実行される順序を変更できます。

タスクは、プロシージャ・エディタの「タスク」タブに表示されている順序で実行されます。この順序の並べ替えが必要になる場合があります。

タスクの順序の変更

  1. プロシージャの「タスク」タブに移動します。

  2. 移動するコマンド行をクリックします。

  3. タスク表のツールバーから、矢印をクリックしてコマンド行を適切な位置に移動します。

プロシージャのコードの記述

式エディタを開いて、プロシージャ内のコードを記述および変更できます。プロシージャ内のコマンドは、いくつかの言語で記述できます。これには次のものがあります。

  • SQL: または、ターゲットのRDBMSでサポートされている言語(PL/SQL、Transact SQLなど)。通常、これらのコマンドには、データ操作言語(DML)またはデータ定義言語(DDL)の文を含めることができます。結果セットを戻すSELECT文またはストアド・プロシージャを使用する場合は、いくつかの制限があります。SQLコマンドを記述するには、次の選択が必要です。

    • SQL文をサポートする有効なRDBMSテクノロジ(Teradata、Oracleなど)。

    • 文が実行される場所を示す論理スキーマ。この論理スキーマは、実行時に、この文を実行する場所として選択された物理データ・サーバーの場所に変換されます。

    • トランザクション処理用の追加情報(RDBMSトランザクションの処理の項を参照)。

    ノート:

    ODIマッピングで使用するSQLコードでは、/*と*/の間にコメントを書きます。

    コメントに--は使用しないでください。

  • オペレーティング・システム・コマンド: 外部プログラムを実行する場合に便利です。この場合、使用するコマンドは、実行を担当するエージェントのオペレーティング・システムのコマンド・インタプリタから実行される動作と同様に動作する必要があります。この動作では、オブジェクトは、エージェントが実行されているプラットフォームに依存しています。オペレーティング・システム・コマンドを記述するには、現在のステップのテクノロジ・リストから「オペレーティング・システム」を選択します。OdiOSCommandツールは、OSコマンド・インタプリタの呼出しや設定が不要であるため、このような種類の操作に使用することをお薦めします。

  • ODIツール: ODIには、特定のタスクを実行するためにプロシージャで使用できる広範囲の組込みツールが用意されています。これらのツールには、ファイル操作、電子メール・アラート、イベント処理などの機能が含まれています。これらのツールの詳細は、オンライン・ドキュメントを参照してください。ODIツールを使用するには、現在のステップのテクノロジ・リストから「ODITools」を選択します。

  • スクリプト言語: コマンドはOracle Data Integratorでサポートされている任意のスクリプト言語で記述できます。ODIがデフォルトでサポートしているスクリプト言語はJython、Groovy、NetRexxおよびJava BeanShellで、現在のステップのテクノロジ・リスト・ボックスからアクセスできます。

    ノート:

    ODIで作成されるJythonスクリプトには、100,000文字を超えることはできないという制限があります。

置換APIの使用

実行のコンテキストに依存しないコマンドをプロシージャに記述する場合は、ODI置換APIの使用をお薦めします。このAPIの詳細は、オンライン・ドキュメントを参照してください。置換APIは通常、次のように使用します。

  • getObjectName()を使用して、実行コンテキストに関係なく、現在の論理スキーマにあるオブジェクトの修飾名をハード・コーディングせずに取得します。

  • getInfo()を使用して、現在のステップに関する一般情報(ドライバ、URL、ユーザーなど)を取得します。

  • getSession()を使用して、現在のセッションに関する情報を取得します。

  • getOption()を使用して、プロシージャの特定のオプションの値を取得します。

  • getUser()を使用して、プロシージャを実行するODIユーザーに関する情報を取得します。

Oracle Data Integratorの置換メソッドを使用してオブジェクト・プロパティにアクセスする場合、フレックスフィールドのコードを指定すると、Oracle Data Integratorは、そのコードをオブジェクト・インスタンスのフレックスフィールド値で置き換えます。フレックスフィールドの作成および使用方法の詳細は、『Oracle Data Integratorでのナレッジ・モジュールの開発』フレックスフィールドの使用に関する項を参照してください。

RDBMSトランザクションの処理

Oracle Data Integratorのプロシージャには、複数のステップまたはプロシージャにわたるトランザクション処理に対する拡張メカニズムが含まれています。トランザクション処理はRDBMSステップにのみ適用され、多くの場合、基礎となるデータベースのトランザクション機能に依存しています。たとえば、プロシージャ内では、エラー発生時にコミットまたはロールバックされる一連のステップを定義できます。また、同じサーバー上でステップに対する依存トランザクション・セットを最大10 (0から9)まで定義できます。基礎となるデータベースがトランザクションをサポートしている場合は、トランザクション処理の使用をお薦めします。トランザクションごとにデータベースへの接続が開くことに注意してください。

ただし、このメカニズムを使用する場合、パラレル環境ではセッション全体でデッドロックが発生する可能性があるため、注意が必要です。

ソース・データとターゲット・データのバインド

Oracle Data Integratorにおけるデータ・バインディングはプロシージャ内のメカニズムで、SQL SELECT文で戻されるすべての行に対してアクションを実行できます。

ソース・データとターゲット・データをバインドするには:

  1. タスク・プロパティで、マウス・ポインタを「ソース・コマンド」または「ターゲット・コマンド」フィールドの上に置き、右側に表示される歯車アイコンをクリックしてコマンド・エディタを開きます。

  2. ソース・コマンド・エディタで、SELECT文を指定します。

  3. ターゲット・コマンド・エディタで、アクション・コードを指定します。アクション・コード自体は、INSERT、UPDATE、DELETEの各SQL文、または他のコード(ODIツール・コール、Jython、Groovyなど)のいずれかです。ODIツール構文の詳細は、Oracle Data Integratorツール・リファレンスを参照してください。

ソース結果セットで戻された値は、SELECT文で戻された列名を使用してアクション・コードで参照できます。これらの値をターゲットのINSERT、UPDATEまたはDELETEの各SQL文で使用する場合は常に、値の先頭にコロン(:)を付ける必要があります。これによって、バインド変数として機能します。ターゲット文がDML文でない場合、これらの値は先頭にハッシュ記号(#)を付ける必要があります。これによって、置換変数として機能します。また、「ソース」タブの結果セットがハッシュ記号(#)を使用して「ターゲット」タブに渡されている場合は、「ソース」タブのコマンドから戻された値の数だけターゲット・コマンドが実行されます。

次に、このメカニズムの一般的な使用例を示します。この強力なメカニズムを使用するアプリケーションは他にも多数あります。

表11-1 リモートSQLデータベースからデータをロードするプロシージャの詳細

詳細 説明

ソース・テクノロジ

Oracle

ソース論理スキーマ

ORACLE_INVENTORY

ソース・コマンド

select PRD_ID       MY_PRODUCT_ID,
       PRD_NAME     PRODUCT_NAME,
from   <%=odiRef.getObjectName("L","PRODUCT","D")%>

ターゲット・テクノロジ

Teradata

ターゲット論理スキーマ

TERADATA_DWH

ターゲット・コマンド

insert into PARTS
(PART_ID, PART_ORIGIN, PART_NAME)
values
(:MY_PRODUCT_ID, 'Oracle Inventory',
:PRODUCT_NAME)

ODIでは、SELECT文で戻されたすべてのレコードが暗黙的にループされ、その値は「:MY_PRODUCT_ID」と「:PRODUCT_NAME」バインド変数にバインドされます。次に、適切なデータ型変換が実行された後、その値を使用してINSERT文がトリガーされます。

ターゲット・テクノロジとソース・テクノロジでそれぞれバッチ更新と配列フェッチがサポートされている場合、ODIでは、すべてのバッチについてメモリー内に配列が準備されます。これによって、トランザクション全体の効率が向上します。

ノート:

このメカニズムは、ターゲット表での高速ロードまたは複数ロードに比較して効率が低いことが判明しています。このメカニズムは、非常に少量のデータに対してのみ使用することを検討してください。

このメカニズムの詳細は、ロード戦略でのエージェントの使用に関する項を参照してください。

表11-2 複数の電子メールを送信するプロシージャの詳細

詳細 説明

ソース・テクノロジ

Oracle

ソース論理スキーマ

ORACLE_DWH_ADMIN

ソース・コマンド

Select FirstName FNAME, EMailaddress EMAIL 
From <%=odiRef.getObjectName("L","Operators","D")%>
Where RequireWarning = 'Yes'

ターゲット・テクノロジ

ODITools

ターゲット論理スキーマ

なし

ターゲット・コマンド

OdiSendMail -MAILHOST=my.smtp.com -FROM=admin@example.com "-TO=#EMAIL" "-SUBJECT=Job Failure"
Dear #FNAME,
I'm afraid you'll have to take a look at ODI Operator, because session <%=snpRef.getSession("SESS_NO")%> has just failed!
-Admin

–TOパラメータは、ソースのSELECT文のEmail列から取得された値に置換されます。したがって、OdiSendMailコマンドは、Operators表に登録されているすべてのオペレータに対してトリガーされます。

例11-1 リモートSQLデータベースからのデータのロード

データをOracle PRODUCT表からTeradata PARTS表に挿入する場合を考えてみます。表11-1に、プロシージャ・ステップでこれを実装する方法の詳細を示します。

例11-2 複数の電子メールの送信

データ・ウェアハウスのロード中に問題が発生したときに、電子メールで警告を受信する全ユーザーの情報が記載された表を考えてみます。表11-2で説明するように、これは単一のプロシージャ・タスクを使用して実行できます。

11.1.3 プロシージャの使用

プロシージャは、次の方法で使用できます。

11.1.3.1 プロシージャの実行

プロシージャを実行するには:

  1. デザイナ・ナビゲータの「プロジェクト」ビューで、実行するプロシージャを選択します。
  2. 右クリックして「実行」を選択します。
  3. 「実行」ダイアログで実行パラメータを設定します。詳細は、『Oracle Data Integratorの管理』実行パラメータの表を参照してください。
  4. 「OK」をクリックします。
  5. 「セッションを開始しました」ウィンドウが表示されます。
  6. 「OK」をクリックします。

ノート:

実行中に、プロシージャでは、プロシージャ・エディタの「オプション」タブに設定されているオプション値が使用されます。

11.1.3.2 パッケージでのプロシージャの使用

プロシージャはパッケージ・ステップとして使用できます。パッケージ・ステップでプロシージャを実行する方法の詳細は、「プロシージャ・ステップの追加」を参照してください。パッケージ・ステップでプロシージャを使用する場合、使用するのは作成済プロシージャのコピーではなく、プロシージャへのリンクです。パッケージの外部でこのプロシージャが変更された場合は、このプロシージャを使用するパッケージも変更されます。

ノート:

プロシージャの「オプション」タブに設定されているオプション値を使用しない場合は、プロシージャ・ステップの「オプション」タブに新規のオプション値を直接設定します。

11.1.3.3 プロシージャのシナリオの生成

本番環境でプロシージャを実行するためのシナリオを生成したり、パッケージを作成せずにプロシージャを使用して実行をスケジュールすることができます。生成したシナリオは、このプロシージャを実行する単一ステップのシナリオとなります。プロシージャのシナリオの生成方法については、シナリオの生成を参照してください。

11.1.4 プロシージャの暗号化と復号化

ナレッジ・モジュール(KM)またはプロシージャを暗号化すると、重要なコードを保護できます。暗号化されたKMまたはプロシージャは、復号化しないかぎり、読み取ったり変更することはできません。暗号化されたKMまたはプロシージャによってログに生成されるコマンドも読み取ることはできません。

Oracle Data Integratorでは、個人暗号化キーに基づいたDES暗号化アルゴリズムが使用されます。このキーは、ファイルに保存して、暗号化操作または復号化操作を実行する際に再利用できます。

警告:

暗号化されたKMまたはプロシージャを暗号化キーなしで復号化する方法はありません。したがって、このキーは安全な場所に保管しておくことを強くお薦めします。また、すべての開発作業で一意のキーを使用することをお薦めします。

プロシージャの暗号化および復号化のステップは、ナレッジ・モジュールの暗号化および復号化のステップと同じです。「ナレッジ・モジュールの暗号化および復号化」で示す手順に従ってください。

11.2 変数の操作

この項では、変数の概要について説明し、Oracle Data Integratorで変数を作成および使用する方法について説明します。この項では、次の項目について説明します。

11.2.1 変数の概要

変数は、単一の値を格納するオブジェクトです。この値には、文字列、数値または日付を使用できます。変数の値はOracle Data Integratorに格納されます。変数はプロジェクト内の複数の場所で使用でき、変数の値は実行時に更新できます。

変数は、そのタイプに応じて次のような特性を備えています。

  • 作成時にデフォルト値を定義できます。

  • 変数の値は、その変数を使用してシナリオを実行するときにパラメータとして渡すことができます。

  • 変数の値は、いずれかのデータ・サーバーで実行された文の結果を使用してリフレッシュできます。たとえば、現在の日時はデータベースから取得できます。

  • 変数の値は、パッケージ・ステップで設定または増分できます。

  • 変数の値は、初期値からセッションの各ステップ実行後の値まで追跡できます。詳細は、「変数と順序の追跡」を参照してください。

  • 変数を評価して、パッケージに条件やブランチを作成できます。

  • 変数は、マッピング、プロシージャ、ステップなどの式やコードで使用できます。

ノート:

ODI変数は、大文字と小文字を区別します。

変数は、任意の式(SQLなど)、およびリポジトリのメタデータ内で使用できます。変数は、その変数が含まれているコマンドがエージェントまたはグラフィカル・インタフェースによって実行される際に解決されます。

変数は、グローバル変数として作成するか、プロジェクト内に作成できます。どちらで作成するかによって、変数の有効範囲が定義されます。グローバル変数はすべてのプロジェクトで使用できますが、プロジェクト変数は、その変数を定義したプロジェクト内でのみ使用できます。

変数の有効範囲の詳細は、変数の使用を参照してください。

次の各項では、変数を作成および使用する方法について説明します。

11.2.2 変数の作成

変数を作成するには:

  1. デザイナ・ナビゲータで、プロジェクト内の「変数」ノードを選択するか、「グローバル・オブジェクト」ビューの「グローバル変数」ノードを選択します。

  2. 右クリックして「新規変数」を選択します。変数エディタが開きます。

  3. 次の変数パラメータを指定します。

    プロパティ 説明

    名前

    変数の名前。変数が使用される書式で指定します。この名前には、変数が使用されるテクノロジでセパレータ(空白など)と解釈される文字は使用できません。変数名は大/小文字が区別されます。したがって、「YEAR」と「year」は2つの異なる変数とみなされます。変数名は最大400文字に制限されています。

    データ型

    変数には次のタイプがあります。

    • 英数字(整数または10進値を表わすテキストを含む、最大255文字のテキスト)

    • 日付 (この書式は、標準仕様のISOの日付と時間の次の書式です。YYYY-MM-DDThh:mm:ssZ)

      ここで大文字のTは、日付要素と時間要素の区切りに使用します。たとえば:

      2011-12-30T13:49:02は、2011年12月30日の午後1時49分2秒を表します。

    • 数値(整数、最大10桁(変数をデジタルとしてリフレッシュすると、デジタル部分が切り捨てられます))

    • テキスト(長さの制限なし)

    履歴の保持

    このパラメータは、変数が保持される値の時間の長さを示します。

    • 履歴なし: 変数の値は、セッションの実行中はメモリー内に保持されます。

    • 最新の値: Oracle Data Integratorでは、変数によって保持される最新の値がリポジトリに格納されます。

    • すべての値: Oracle Data Integratorでは、この変数が持つすべての値の履歴が保持されます。

    セキュアな値

    変数が記録されないようにする場合は、「セキュアな値」を選択します。これは、変数にパスワードやその他の機密データが含まれている場合に便利です。「セキュアな値」が選択されている場合:

    • 変数は追跡されません: 変数はソース・コードまたはターゲット・コードで未解決の状態で表示され、リポジトリでの追跡や履歴化は行われません。

    • 「履歴の保持」パラメータは自動的に「履歴なし」に設定され、編集できません。

    デフォルト値

    デフォルトで変数に割り当てられた値。

    説明

    変数の詳細な説明。

  4. 変数の値を問合せで設定する場合は、次の手順を実行します。

    1. 「リフレッシュ中」タブを選択します。

    2. コマンドを実行する論理スキーマを選択し、スキーマのテクノロジの言語でコマンド・テキストを編集します。コマンド・テキストは式エディタを使用して編集できます。問合せ式の構文には、getObjectNameなどの置換メソッドを使用することをお薦めします。

    3. 「DBMSで問合せをテスト中」 をクリックして、式の構文をチェックします。

    4. 「リフレッシュ」をクリックし、問合せを即時に実行して変数をテストします。「履歴の保持」パラメータが「すべての値」または「最新の値」に設定されている場合は、変数エディタの「履歴」タブに戻り値を表示できます。変数の値がどのように計算されるかの詳細は、「変数値のリフレッシュに関するノート」を参照してください。

  5. 「ファイル」メニューから「保存」を選択します。

デザイナ・ナビゲータの「プロジェクト」または「グローバル・オブジェクト」セクションに変数が表示されます。

ヒント:

変数の参照には、式エディタの使用をお薦めします。式エディタを使用すると、一般的な構文エラーを回避できます。たとえば、式エディタで変数を選択すると、その変数の有効範囲に応じて変数名の先頭に適切なコードが自動的に付きます。変数の参照方法の詳細は、「変数の有効範囲」を参照してください。

変数値のリフレッシュに関するノート

  • 数値のセッション変数は、デフォルト値なしで定義されることがあります。セッション変数の以前の値がリポジトリ内にも残っていない場合、その変数値は未定義であるとみなされます。このような数値のセッション変数の値の問合せが行われた場合(たとえば、リフレッシュ中に問合せがあった場合)、ODIからは0が結果として返されます。

  • 数値以外のセッション変数(日付、英数字、テキストなど)がデフォルト値なしで定義されている場合、このような変数の値の問合せが行われると、「ODI-17506: 変数に値がありません: <var_name>」エラーが発生します。

  • ロード計画変数は、デフォルト値および永続的な値を持ちません。開始時に、ロード計画では変数のデフォルト値、または実行コンテキスト内の変数の履歴化された値/最新値は考慮されません。変数の値は、ロード計画の開始時に指定した値、またはロード計画内で設定/リフレッシュした値です。ロード計画変数が起動値として渡されない場合、ロード計画変数の起動値は未定義であるとみなされます。さらに、この変数がリフレッシュされず、ロード計画ステップで上書きされない場合は、ステップ内の変数の値も未定義になります。数値のロード計画変数の値が未定義である場合は、数値のセッション変数と同じように動作し、たとえば値の問合せが行われると、0が返されます。詳細は、「ロード計画での変数の使用」を参照してください。

  • 数値以外のロード計画変数については、現在のODIリポジトリの設計では、未定義の値とnullの値の保持を区別できないという制限があります。そのため、数値以外のロード計画変数の値が未定義である場合、現時点では、null値が保持されているものとしてODIで処理されます。

  • コマンドや式(SQLテキストなど)で、null値を持つセッション変数またはロード計画変数が参照された場合は、空の文字列(""の二重引用符なしの長さが0の文字列)が、テキストの変数参照の値として使用されます。

11.2.3 変数の使用

再利用可能なパッケージ、または複雑な条件ロジック、マッピングおよびプロシージャが含まれるパッケージを作成する場合は、変数の使用をお薦めします。変数は、ODI内のすべての場所で使用できます。変数の値は、「履歴の保持」 パラメータが「すべての値」または「最新の値」に設定されている場合は、ODIリポジトリに永続的に保存されます。または、「履歴の保持」 パラメータが「履歴なし」に設定されている場合は、現在のセッションの実行中に限り、変数の値がエージェントのメモリーに保持されます。

この項では、Oracle Data Integratorでの変数の使用方法の概要を説明します。変数は、次のように使用できます。

変数の有効範囲

パッケージ、マッピングおよびプロシージャの変数を参照するには、式エディタを使用します。式エディタを使用すると、変数はリポジトリから直接取得されます。

式エディタが使用できない場合は、変数名の先頭にGLOBALまたはPROJECT_CODEを手動で付ける必要があります。

オブジェクト内のMY_VARという変数を参照するには、次のように行います。

  • #MY_VAR: この構文を使用する場合は、変数とその変数を参照するオブジェクトは同じプロジェクトに存在している必要があります。変数の値は置換されます。正確に指定するために、変数名の先頭にプロジェクト名を付けた完全修飾構文を使用することを検討してください。

  • #MY_PROJECT_CODE.MY_VAR: この構文を使用すると、変数を含むプロジェクトを明示的に示して変数を使用できます。たとえば、グローバル・レベルとプロジェクト・レベルに同じ名前の変数が2つ存在する場合でも、正確に指定できます。変数の値は実行時に置換されます。

  • #GLOBAL.MY_VAR: この構文を使用すると、グローバル変数を参照できます。変数の値はコード内で置換されます。詳細は、グローバル・オブジェクトに関する項を参照してください。

  • ハッシュ(#)ではなくコロン(:)を使用: 変数の先頭にハッシュ記号ではなくコロンを付けると、変数をSQLバインド変数として使用できます。ただし、この構文はSQL DML文にのみ適用され、OSコマンドやODI APIコールには適用されないという制約があります。さらに、バインド変数を使用すると、パフォーマンスが低下する場合があります。実行時に最適なパフォーマンスを得るには、#文字を先頭に付けたODI変数の使用をお薦めします。

    • 先頭にコロン(:)が付いたODI変数を参照すると、RDBMSエンジンで実行計画を決定するときに変数の名前が置換されません。変数が置換されるのは、RDBMSでリクエストが実行されるときです。このメカニズムをバインディングと呼びます。バインディング・メカニズムを使用する場合、RDBMSでは変数が使用される列の定義で指定されたタイプと同じタイプのデータが使用されるとみなされるため、文字列を格納する変数をデリミタ(引用符など)で囲む必要はありません。

      たとえば、変数TOWN_NAME = :GLOBAL.VAR_TOWN_NAME を使用する場合は、VARCHAR型が使用されるとみなされます。

    • 先頭に#文字が付いたODI変数を参照すると、テクノロジでコードが実行される前に、変数の名前が値で置換されます。変数参照は一重引用符で囲む必要があります(たとえばTOWN = '#GLOBAL.VAR_TOWN')。変数のこの参照モードは、OSコマンド、SQLおよびODI APIコールに対して機能します。

11.2.3.1 パッケージでの変数の使用

変数は、次のような様々な目的でパッケージ内で使用できます。

  • 変数の宣言: 変数をパッケージで(またはパッケージ内で使用されるトポロジの特定の要素で)使用する場合は、そのパッケージに変数の宣言ステップを挿入することを強くお薦めします。このステップは、パッケージの変数を明示的に宣言します。変数の宣言ステップの作成方法については、「変数ステップの追加」を参照してください。値を設定、リフレッシュまたは評価するためにパッケージで明示的に使用する他の変数は、宣言する必要がありません。

  • SQL SELECT文からの変数のリフレッシュ: 変数のリフレッシュ・ステップでは、変数値を計算するコマンドまたは問合せを再実行できます。変数のリフレッシュ・ステップの作成方法については、「変数ステップの追加」を参照してください。

  • 変数の値の割当て: 「割当て」タイプの変数の設定ステップでは、変数の現在の値を設定します。

    Oracle Data Integratorでは、次の方法で変数に値を割り当てることができます。

    • SQL SELECT文から変数値を取得する方法: 変数の作成時に、変数値を取得するSQL文を定義します。たとえば、変数NB_OF_OPEN_ORDERSを作成し、SQL文をselect COUNT(*) from <%=odiRef.getObjectName("L","ORDERS","D")%> where STATUS = 'OPEN'に設定できます。

      次に、パッケージで変数をドラッグ・アンド・ドロップし、「プロパティ」パネルで「変数のリフレッシュ」オプションを選択します。これによって、実行時にODIエージェントがSQL文を実行し、結果セットの最初の戻り値を変数に割り当てます。

    • パッケージに値を明示的に設定する方法: パッケージの有効範囲内で、変数に値を手動で割り当てることもできます。変数をパッケージにドラッグ・アンド・ドロップし、「プロパティ」パネルで「変数の設定」および「割当て」オプションを選択し、設定する値を指定します。

    • 値を増分する方法: 増分が適用されるのは、数値データ型を使用して定義された変数のみです。数値変数をパッケージにドラッグ・アンド・ドロップし、「プロパティ」パネルで「変数の設定」および「増分」オプションを選択し、任意の増分を指定します。増分値には正の数または負の数を指定できます。

    • 実行時に値を割り当てる方法: 変数を含むパッケージから生成されたシナリオを開始するときに、その変数の値を設定できます。これを行うには、StartScenarioコマンドでVARIABLE=VALUEリストを指定します。『Oracle Data Integratorツール・リファレンス』のAPIコマンドOdiStartLoadPlanに関する項、および『Oracle Data Integratorの管理』コマンドラインからのシナリオの実行に関する項を参照してください。

      変数の割当てステップの作成方法については、「変数ステップの追加」を参照してください。

  • 数値の増分: 「増分」タイプの変数の設定ステップでは、指定した量のみ数値を増減します。変数の設定ステップの作成方法については、「変数ステップの追加」を参照してください。

  • 条件ブランチの値の評価: 変数の評価ステップはIF-ELSEステップと同様に機能します。比較の結果に基づいて、パッケージ内の変数およびブランチの現在値をテストします。たとえば、変数EXEC_A_AND_BがYESに設定されている場合のみ、マッピングAとBを実行し、そうでない場合はマッピングBとCを実行するとします。これを行うには、変数をパッケージ・ダイアグラムにドラッグ・アンド・ドロップし、「プロパティ」パネルで「変数の評価」タイプを選択します。パッケージの変数を評価することによって、再利用可能で複雑なワークフローを柔軟に設計できます。変数の評価ステップの作成方法については、「変数ステップの追加」を参照してください。

11.2.3.2 マッピングでの変数の使用

変数は、次の2つの方法でマッピング内で使用できます。

  1. ナレッジ・モジュールのテキスト・オプションの値として使用する方法

  2. フィルタ条件や結合条件など、Oracle Data Integratorのあらゆる式で使用する方法

変数の値を式のテキストに置換するには、変数名の前に#文字を追加します。エージェントまたはグラフィカル・インタフェースによって、実行前にコマンドの変数の値が置換されます。

次に、YEARというグローバル変数の使用例を示します。

Update CLIENT set LASTDATE = sysdate where DATE_YEAR = '#GLOBAL.YEAR' /* DATE_YEAR is CHAR type */
Update CLIENT set LASTDATE = sysdate where DATE_YEAR = #GLOBAL.YEAR /* DATE_YEAR is NUMERIC type */

SQL言語のバインド変数メカニズムも使用できますが、あまり効率的ではありません。これは、リレーショナル・データベース・エンジンでは、問合せの実行計画の作成時に変数の値を認識できないためです。このメカニズムを使用するには、変数の先頭に「:」文字を付けて、検索対象のデータ型が変数のデータ型に適合するようにします。たとえば:

update CLIENT set LASTDATE = sysdate where DATE_YEAR =:GLOBAL.YEAR

フィルタまたは結合式に使用される日付型変数には、"バインド変数"メカニズムを使用する必要があります。次の例は、フィルタを示しています。

SRC.END_DATE > :SYSDATE_VAR 

変数SYSDATE_VARは、リフレッシュ問合せselect sysdate from dualを持つ"日付"型変数です

日付変数に置換メソッドが使用される場合、RDBMS固有の変換関数を使用して、文字列を日付形式に変換する必要があります。

式エディタでは、ほとんどの式に変数をドラッグ・アンド・ドロップできます。

表11-3 マッピングでの変数の使用例

タイプ 説明

属性式

'#PRODUCT_PREFIX' || PR.PRODUCT_CODE

現在のプロジェクトのPRODUCT_PREFIX変数をPRODUCT_CODEに連結します。変数の値は置換されて文字列を戻すため、変数を一重引用符で囲む必要があります。

結合条件

CUS.CUST_ID = #DEMO.UID * 1000 + FF.CUST_NO

DEMOプロジェクトのUID変数の値に1000を乗算し、CUST_NO列を加算してから、CUST_ID列に結合します。

フィルタ条件

ORDERS.QTY between #MIN_QTY and #MAX_QTY

MIN_QTYとMAX_QTYのしきい値に従って注文をフィルタ処理します。

オプション値

TEMP_FILE_NAME: #DEMO.FILE_NAME

FILE_NAME変数をTEMP_FILE_NAMEオプションの値として使用します。

11.2.3.3 オブジェクト・プロパティでの変数の使用

トポロジのリソース名やスキーマ名などのグラフィカル・モジュールのフィールドでは、変数を置換変数として使用することも可能です。この場合、Oracle Data Integratorのグラフィカル・モジュールのフィールドでは、変数の完全修飾名(例: #GLOBAL.MYTABLENAME)を直接使用する必要があります。

この方法を使用すると、実行時の次のような要素をパラメータ化できます。

  • ファイルや表の物理名(データストアの「リソース」フィールド)、またはその場所(トポロジの物理スキーマのスキーマ(データ))

  • 物理スキーマ

  • データ・サーバーURL

11.2.3.4 プロシージャでの変数の使用

表11-4に示すように、変数はプロシージャのコード内で使用できます。

表11-4 プロシージャでの変数の使用例

ステップID: ステップ・タイプ ステップ・コード 説明

1

SQL

Insert into #DWH.LOG_TABLE_NAME

Values (1, 'Loading Step Started', current_date)

実行時にのみ名前が判明するログ表に行を追加します。

2

Jython

f = open('#DWH.LOG_FILE_NAME', 'w')

f.write('Inserted a row in table %s' % ('#DWH.LOG_TABLE_NAME') )

f.close()

LOG_FILE_NAME変数で定義されるファイルを開き、行を挿入したログ表の名前を書き込みます。

プロシージャでは、できるだけ、変数ではなくオプションを使用することを検討してください。オプションは入力パラメータと同様に機能します。したがって、パッケージ内のプロシージャを実行するときは、オプション値を適切な値に設定できます。

表11-4の例では、ステップ1のコードは次のように記述します。

Insert into <%=snpRef.getOption("LogTableName")%> 
Values (1, 'Loading Step Started', current_date)

次に、プロシージャをパッケージ・ステップとして使用するときは、LogTableNameオプションの値を#DWH.LOG_TABLE_NAMEに設定します。

Groovyスクリプトを使用している場合、"#varname""#GLOBAL.varname"のように、変数名を二重引用符(")で囲む必要があります。そうしないと、変数はODI変数値に置き換えられません。

11.2.3.5 変数内での変数の使用

表11-5に示すように、他の変数値に依存する変数を使用すると便利な場合があります。

表11-5 別の変数内での変数の使用例

変数名 変数の詳細 説明

STORE_ID

英数字変数。パラメータとしてシナリオに渡されます。

店舗のIDを指定します。

STORE_NAME

英数字変数。

SELECT文:

Select name
From <%=odiRef.getObjectName("L","STORES","D")%>
Where id='#DWH.STORE_ID'||'#DWH.STORE_CODE'

現在の店舗の名前は店舗表から導出されます。この店舗表は、STORE_ID変数とSTORE_CODE変数の連結によって戻された値によってフィルタ処理された表です。

表11-5の場合、次のようにしてパッケージを構築します。

  1. STORE_ID変数をドラッグ・アンド・ドロップして宣言します。これによって、実行時にこの変数をシナリオに渡すことができます。

  2. STORE_NAME変数をドラッグ・アンド・ドロップして、その値をリフレッシュします。このステップを実行すると、エージェントは適切なSTORE_ID値を使用して問合せの選択を実行し、対応するSTORE_NAME値を取得します。

  3. これらの変数を使用する他のマッピングまたはプロシージャをドラッグ・アンド・ドロップします。

"バインド変数"メカニズムを使用して、他の"日付"型変数を参照する"日付"型変数のリフレッシュ問合せを定義する必要があります。たとえば:

VAR1"日付"型変数は、リフレッシュ問合せselect sysdate from dualを持ちます

VAR_VAR1"日付"型変数は、リフレッシュ問合せselect :VAR1 from dualを持つ必要があります

11.2.3.6 データストアのリソース名での変数の使用

ソースまたはターゲット・データストアの名前が動的である場合があります。一般的な例には、接頭辞と動的な接尾辞(現在日付など)で構成されたファイル名を使用して、フラット・ファイルをデータ・ウェアハウスにロードする場合があります。たとえば、3月26日の注文ファイルの名前はORD2009.03.26.datになります。

以前に宣言されている変数を使用できるのは、シナリオ内のデータストアのリソース名のみであることに注意してください。

ノート:

連結された複数の変数は、データストアのリソース名には使用できません。必要に応じて、単一の変数のリフレッシュ・ロジック内に、より複雑な文字列連結を追加できます。

ロード・マッピングを開発するには、次のステップを実行します。

  1. DWHプロジェクトにFILE_SUFFIX変数を作成し、そのSQL SELECT文でcurrent_date (または実際のファイル接尾辞の書式に一致する適切な日付変換)を選択するように設定します。

  2. モデル内にORDERSファイル・データストアを定義し、そのリソース名をORD#DWH.FILE_SUFFIX.datに設定します。

  3. 通常は、マッピングにファイル・データストアを使用します。

  4. 次のようにパッケージを設計します。

    1. FILE_SUFFIX変数をドラッグ・アンド・ドロップしてリフレッシュします。

    2. ORDERSデータストアを使用するすべてのマッピングをドラッグ・アンド・ドロップします。

これで、実行時に、ソース・ファイル名が適切な値に置換されます。

ノート:

データストアのリソース名の変数は、そのプロジェクト・コードを使用して完全修飾する必要があります。

このメカニズムを使用しているときは、デザイナ内からデータストアのデータを表示できません。

11.2.3.7 サーバーURLでの変数の使用

異なる場所ごとにコンテキストを使用するよりも、データ・サーバーのURL定義に変数を使用するほうが適切な場合があります。たとえば、ソースの数が多い(100以上)場合や、トポロジが外部の別の表に定義されている場合は、サーバーの定義のURLに含まれる変数を参照できます。

Oracleデータベースでホストされ、店舗で使用している250のソース・アプリケーションからウェアハウスをロードする場合を考えてみます。店舗ごとに1つのコンテキストを定義する方法も可能ですが、この方法ではトポロジが複雑になり、保守が困難になります。かわりに、店舗に接続するためのすべての物理情報を参照する表を定義し、データ・サーバーの定義のURLに変数を使用できます。例11-3に、Oracle Data Integratorでの実装方法を示します。

例11-3 サーバーの定義のURLでの変数の参照

  1. 次のように、StoresLocation表を作成します。

    店舗ID 店舗名 店舗URL IsActive

    1

    Denver

    10.21.32.198:1521:ORA1

    YES

    2

    San Francisco

    10.21.34.119:1525:SANF

    NO

    3

    New York

    10.21.34.11:1521:NY

    YES

    ...

    ...

    ...

    ...

  2. EDWプロジェクトに次の3つの変数を作成します。

    • STORE_ID: 入力パラメータとして現在の店舗IDを使用します。

    • STORE_URL: SELECT文select StoreUrl from StoresLocation where StoreId = #EDW.STORE_IDを使用して、現在の店舗IDに対する現在のURLをリフレッシュします。

    • STORE_ACTIVE: SELECT文select IsActive from StoresLocation where StoreId = #EDW.STORE_IDを使用して、現在の店舗IDに対する現在のアクティビティ・インジケータをリフレッシュします。

  3. 全店舗用に1つの物理データ・サーバーを定義し、そのJDBC URLを次のように設定します。

    jdbc:oracle:thin:@#EDW.STORE_URL

  4. 店舗からデータをロードするためのパッケージを定義します。

    入力変数STORE_IDを使用して、StoresLocation表のSTORE_URL変数とSTORE_ACTIVE変数の値をリフレッシュします。STORE_ACTIVEがYESに設定されている場合は、次の3ステップがトリガーされます。マッピングでは、STORE_URL変数の値に従って、エージェントが存在するソース・データストアを参照します。

    New York店についてUNIXでこのシナリオを開始するには、次のオペレーティング・システム・コマンドを発行します。

    startscen.sh LOAD_STORE 1 PRODUCTION "EDW.STORE_ID=3"

    すべての店舗についてLOAD_STOREシナリオを並行してトリガーする場合は、次のように単一のSELECT/アクション・コマンドを使用するプロシージャを作成する必要があります。

    詳細 説明

    ソース・テクノロジ

    Oracle (StoresLocation表を含むデータ・サーバーのテクノロジ)。

    ソース論理スキーマ

    StoresLocation表を含む論理スキーマ。

    ソース・コマンド

    Select StoreId
    From StoresLocation

    ターゲット・テクノロジ

    ODITools

    ターゲット論理スキーマ

    なし

LOAD_STOREシナリオは、適切なSTORE_ID値を使用してすべての店舗に対して実行されます。店舗に対応するURLが設定されます。

詳細は、『Oracle Data Integratorの管理』ソースおよびターゲット・データのバインドに関する項およびエージェントの管理に関する項を参照してください。

11.2.3.8 接続時または切断時のコマンドでの変数の使用

接続時または切断時のSQLコマンドには変数を使用できます。詳細は、『Oracle Data Integratorの管理』データ・サーバーの作成(詳細設定)に関する項を参照してください。

11.2.3.9 シナリオへの変数の受渡し

動作をカスタマイズするために変数をシナリオに渡すこともできます。これを行うには、シナリオを実行するOSコマンド行で変数の名前とその値を渡します。詳細は、『Oracle Data Integratorの管理』コマンドラインからのシナリオの実行に関する項を参照してください。

11.2.3.10 変数のシナリオの生成

変数をリフレッシュするために単一ステップのシナリオを生成できます。

変数のシナリオを生成する方法については、シナリオの生成を参照してください。

11.2.3.11 変数と順序の追跡

変数と順序を追跡すると、実行済のセッション中に使用されたOracle Data Integratorユーザー変数の実際の値を判断できます。また、変数の追跡機能では、変数がソース/ターゲット操作で使用されたのか、または評価ステップなどの内部操作で使用されたのかも判断できます。

変数の追跡は複数のレベルで実行および構成されます:

  • 変数を定義するときに、変数が記録されないようにする場合は「セキュアな値」を選択します。これは、変数にパスワードやその他の機密データが含まれている場合に便利です。「セキュアな値」を選択すると、変数は追跡されません。変数はソース・コードまたはターゲット・コードに未解決の状態で表示され、リポジトリでの追跡や履歴化は行われません。詳細は、「変数の作成」を参照してください。

  • セッションの実行時または再開時には、「実行」または「セッションの再開」ダイアログで「ログ・レベル6」を選択すると、変数の追跡を有効にできます。ログ・レベル6は、ログ・レベル5と動作は同じですが、変数の追跡が追加されています。

  • オペレータ・ナビゲータで実行結果を確認する場合、次を行えます:

    • セッション・ステップ・エディタまたはセッション・タスク・エディタの「変数値と順序値」 セクションで、追跡された変数と順序を表示します。

    • セッション・タスク・エディタで、実行のソース/ターゲット操作を確認します。解決済の変数値および順序値とともにコードを表示するには、セッション・タスク・エディタの「コード」タブで「値の表示/非表示」をクリックします。解決済の変数値には置換モードの変数(#VARIABLE)のみ表示され、変数値が表示される場合、コードが読取り専用であることに注意してください。

変数と順序の追跡は、デバッグ目的に役立ちます。オペレータ・ナビゲータでのエラーの分析方法および変数追跡の有効化方法の詳細は、『Oracle Data Integratorの管理』失敗したセッションの処理に関する項を参照してください。

変数の追跡は、ODI StudioセッションとODIコンソール・セッションで使用できます。

Oracle Data Integratorで変数を追跡する場合は、次の点に注意してください:

  • セッション中に変数がとる値ごとに追跡できます。

  • 追跡されたすべての変数の値は、ステップ・レベルおよびタスク・レベルで表示できます。これには変数がステップまたはタスクによって変更された場合も含まれ、ステップ・エディタまたはタスク・エディタに変数の名前と新しい値が表示されます。

  • ステップまたはタスクのソース・コードとターゲット・コードは、解決済の変数値および順序値とともに表示することも、変数名と順序名を表示して変数値は非表示にすることもできます。変数値が表示されている場合、コードは読取り専用になることに注意してください。

  • 「セキュアな値」として定義された変数(パスワードなど)は、解決済のコード・リストにも変数リストにも表示されません。セキュアな変数は、リフレッシュされても、リポジトリに値が保持されません。また、セキュアな変数のリフレッシュは、2つのセッション間では機能しません。

  • セッションがパージされると、そのセッションについて追跡されるすべての変数値もセッションとともにパージされます。

  • バインド変数(:VARIABLE_NAME)とネイティブ順序(:<SEQUENCE_NAME>_NEXTVAL)はソース・コードとターゲット・コードで値が解決されず、置換された変数と順序(#VARIABLE_NAME#<SEQUENCE_NAME>_NEXTVAL)のみが解決されます。

  • 追跡された値は、セッションがエクスポートまたはインポートされるときに、セッションの一部としてエクスポートおよびインポートされます。

11.3 順序の使用

この項では、順序の概要について説明し、Oracle Data Integratorで順序を作成および使用する方法について説明します。この項には次のトピックが含まれます:

11.3.1 順序の概要

順序は、使用されるたびに自動的に増分する変数です。次の使用までの間、値はリポジトリに格納されるか、外部RDBMS表内で管理されます。順序には、文字列、リスト、タプルまたはディクショナリを使用できます。

Oracle Data Integratorの順序は、RDBMSエンジンからネイティブ順序をマップしたり、RDBMSエンジンにネイティブ順序が存在しない場合に順序をシミュレートすることを目的にしています。ネイティブ以外の順序の値は、リポジトリに格納するか、外部RDBMS表のセル内で管理できます。

順序は、グローバル順序として作成するか、またはプロジェクト内で作成することが可能です。グローバル順序はすべてのプロジェクトに共通ですが、プロジェクト順序はそれを定義したプロジェクト内でのみ使用できます。

Oracle Data Integratorでは3つのタイプの順序がサポートされています。

  • 標準順序: 現在の値がリポジトリに格納されます。

  • 特定の順序: 現在の値がRDBMS表のセルに格納されます。Oracle Data Integratorは、値を読み取り、行をロックして(同時更新の場合)、最後の増分後に行を更新します。

  • ネイティブ順序: RDBMSが管理する順序をマップします。

標準順序および特定の順序については、次の点に注意してください。

  • Oracle Data Integratorでは、複数ユーザー管理に使用される順序をロックしますが、順序の再開位置については処理しません。つまり、SQL文のROLLBACKでは、トランザクションの開始時の値に順序を戻すことはできません。

  • Oracle Data Integratorの標準順序および特定の順序は、一部のRDBMSで順序が存在しないことを補う目的で開発されています。ネイティブ順序が存在する場合は、その順序を使用してください。これによって、エージェントとデータベース間の対話が減少するため、処理速度が向上する可能性があります。

  • 標準順序と特定の順序の値(#<SEQUENCE_NAME>_NEXTVAL)は追跡できます。ネイティブ順序の追跡時にのみ発生する悪影響は、ネイティブ順序値が、追跡目的でアクセスされるときにもう一度増分されることです。詳細は、「変数と順序の追跡」を参照してください。

次の各項では、順序を作成および使用する方法について説明します。

11.3.2 順序の作成

順序を作成する手順は、順序タイプによって異なります。該当する項を参照してください。

11.3.2.1 標準順序の作成

標準順序を作成するには:

  1. デザイナ・ナビゲータで、プロジェクト内の「順序」ノードを選択するか、「グローバル・オブジェクト」ビューの「グローバル順序」ノードを選択します。
  2. 右クリックして「新規順序」を選択します。順序エディタが開きます。
  3. 順序の「名前」を入力し、「標準順序」を選択します。
  4. 「増分」に入力します。
  5. 「ファイル」メニューから「保存」をクリックします。

デザイナ・ナビゲータの「プロジェクト」または「グローバル・オブジェクト」セクションに順序が表示されます。

11.3.2.2 特定の順序の作成

順序値を特定のデータ・スキーマ内の表に格納する場合、このオプションを選択します。

特定の順序を作成するには:

  1. デザイナ・ナビゲータで、プロジェクト内の「順序」ノードを選択するか、「グローバル・オブジェクト」ビューの「グローバル順序」ノードを選択します。
  2. 右クリックして「新規順序」を選択します。順序エディタが開きます。
  3. 順序の「名前」を入力し、「特定の順序」を選択します。
  4. 「増分」の値を入力します。
  5. 次の順序パラメータを指定します。
    スキーマ 順序表を含む論理スキーマ

    順序値を含む表

    順序値を含む列の名前

    単一行を取得するフィルタ

    順序表に複数の行が含まれている場合に、Oracle Data Integratorで表内の特定の行を検索できるようにフィルタを入力します。このフィルタによって、データ・サーバーのSQL構文が取得されます。

    たとえば: CODE_TAB = '3'

    フィルタは、式エディタを使用して編集できます。「DBMSで問合せをテスト中」 をクリックして、式の構文をチェックします。

  6. 「ファイル」メニューから「保存」をクリックします。

デザイナ・ナビゲータの「プロジェクト」または「グローバル・オブジェクト」セクションに順序が表示されます。

ノート:

Oracle Data Integratorで特定の順序の値にアクセスする場合、スキーマで実行される問合せは、SELECT 列 FROM 表 WHERE フィルタの形式となります。

11.3.2.3 ネイティブ順序の作成

順序がデータベース・エンジンに実装される場合、このオプションを選択します。位置および増分は、データベース・エンジンによって完全に処理されます。

ネイティブ順序を作成するには:

  1. デザイナ・ナビゲータで、プロジェクト内の「順序」ノードを選択するか、「グローバル・オブジェクト」ビューの「グローバル順序」ノードを選択します。
  2. 右クリックして「新規順序」を選択します。順序エディタが開きます。
  3. 順序の「名前」を入力し、「ネイティブ順序」を選択します。
  4. ネイティブ順序を含む論理スキーマ を選択します。
  5. 「ネイティブ順序名」 に入力するか、「参照」ボタンをクリックして、データ・サーバーから取得されたリストから順序を選択します。
  6. 「参照」ボタンをクリックした場合は、「ネイティブ順序選択」 ダイアログで「コンテキスト」を選択して、論理スキーマのこのコンテキストでの順序リストを表示します。
  7. いずれかの順序を選択して、「OK」をクリックします。
  8. 「ファイル」メニューから「保存」をクリックします。

デザイナ・ナビゲータの「プロジェクト」または「グローバル・オブジェクト」ツリーに順序が表示されます。

11.3.3 順序およびID列の使用

順序を増分するには、エージェントがデータを1行ずつ処理する必要があります。したがって、多数のレコードを処理する場合に順序を使用することはお薦めできません。このような場合は、データベース固有の順序(Teradata、IBM DB2、Microsoft SQL ServerのID列、またはOracleの順序など)を使用します。

順序は、Oracle Data Integratorのすべての式で使用できます。たとえば:

  • コンポーネント属性の「式」プロパティ

  • フィルタ・コンポーネントの「フィルタ条件」プロパティ

  • 結合コンポーネントの「結合条件」プロパティ

順序は、次のいずれかとして使用できます。

  • 置換された値。#<SEQUENCE_NAME>_NEXTVAL 構文を使用します。

  • SQL文のバインド変数。:<SEQUENCE_NAME>_NEXTVAL 構文を使用します。

置換された値として順序を使用する場合

順序は、#<SEQUENCE_NAME>_NEXTVAL構文を使用して、すべての文で使用できます。

この構文を使用すると、コマンドの実行前に順序値が1回のみ増分され、その値でコマンドのテキストが置換されます。順序値はすべてのレコードで同一になります。

バインド変数として順序を使用する場合

順序は、KMまたはプロシージャのターゲット・コマンドのSQL文の場合のみ、:<SEQUENCE_NAME>_NEXTVAL構文で使用できます。

この構文を使用すると、順序値が増分され、ターゲットSQLコマンドのバインド変数として渡されます。順序値は、コマンドによるレコードの処理ごとに増分されます。順序タイプに応じて動作が異なります。

  • ネイティブ順序は常に、レコードが処理されるたびに増分されます。

  • 標準順序および特定の順序は、ランタイム・エージェントによって解決され、レコードがエージェントを経由した場合のみ増分されます。このような順序を使用するKMまたはプロシージャのコマンドでは、ターゲット・コマンドで単一のINSERT/UPDATE...SELECTを使用するのではなく、ソース・コマンドでSELECT文を使用し、ターゲット・コマンドでINSERTまたはUPDATE文を使用する必要があります。

ノート:

行ごとに順序が増分するのは、次の場合のみです。

  • ステージング領域がターゲット上にない場合

  • アクセス・ポイントでLKM SQL Multi-Connectを使用する場合

  • ターゲット・データストアでIKM SQL to SQL Control AppendなどのマルチテクノロジIKMを使用する場合

たとえば:

  • SQL文insert into fac select :NO_FAC_NEXTVAL, date_fac, mnt_facでは、SQL文が10,000行を処理した場合でも、標準順序または特定の順序の値が増分されるのは1回のみです。これは、エージェントが各レコードを処理するのではなく、データベース・エンジンにコマンドを送信するのみであるためです。ネイティブ順序は行ごとに増分されます。

  • 行ごとに標準順序または 特定の順序の値を増分するには、データがエージェントを経由する必要があります。これを行うには、ソース・コマンドでSELECTを実行し、ターゲット・コマンドでINSERTを実行するKMまたはプロシージャを使用します。

    SELECT date_fac, mnt_fac /* on the source connection */
    
    INSERT into FAC (ORDER_NO, ORDER_DAT, ORDER_AMNT) values (:NO_FAC_NEXTVAL, :date_fac, :mnt_fac) /* on the target connection */
    

順序の有効範囲

変数とは異なり、順序の有効範囲はコード内で明示的に宣言する必要はありません。

11.3.3.1 標準順序および特定の順序を使用する際のヒント

表に挿入された各行で順序が確実に更新されるには、各行がエージェントで処理される必要があります。この動作を保証するには、次のステップを実行します。

  1. ターゲットで実行される順序を格納するマッピングを作成します。
  2. 挿入に対してのみアクティブになるようにマッピングを設定します。順序に対する更新はサポートされません。
  3. 増分更新のIKMを使用する場合は、順序が移入される列が使用中の更新キーに含まれていないことを確認します。たとえば、データストアの主キーをロードするために順序を使用する場合は、マッピングの更新キーとして代替キーを使用する必要があります。
  4. Oracle Data Integratorの順序をバインド構文(:<SEQUENCE_NAME>_NEXTVAL)で使用する場合は、IKMによってすべてのデータがエージェント経由で転送されるようにデータ・フローを構成する必要があります。これは、生成された統合ステップをオペレータでチェックすることにより検証できます。異なる接続では、単一のSELECT...INSERT文ではなく個別のINSERTコマンドとSELECTコマンドを実行する必要があります。

Example 11-4 順序の制限

順序には次の制限があります。

  • 順序とともにマップされた列では、not nullをチェックできません。

  • 同様に、順序を参照している主キーまたは代替キーでは、静的制御およびフロー制御を実行できません。

11.3.3.2 ID列

一部のデータベースでは、増分する一意の値が自動的に移入されるID列をネイティブで提供しています。

ID列を移入する場合は、次のステップを実行する必要があります。

  1. ID列をロードするマッピングは、空白および非アクティブにする必要があります。挿入または更新に対してアクティブにしないでください。
  2. 増分更新のIKMを使用する場合は、使用中の更新キーにID列が含まれていないことを確認します。ID列が主キーに含まれている場合は、マッピングの更新キーとして代替キーを定義する必要があります。

例11-5 ID列の制限

ID列には次の制限があります。

  • ID列ではnot nullをチェックできません。

  • ID列を含む主キーまたは代替キーでは、静的制御およびフロー制御を実行できません。

11.3.4 順序の拡張

Oracle Data Integratorの順序が、CURRVAL演算子をサポートするように拡張されました。図11-1に示されているように、式エディタで、「ODIオブジェクト」パネルにリストされている各順序に対してNEXTVALおよびCURRVAL演算子が表示されるようになりました。

ネイティブ順序の現在の値を使用する前に、次のことを行ってください。

  • テクノロジでネイティブ順序がサポートされていることを確認します。たとえば、MySQLではネイティブ順序はサポートされていません。

  • ローカル順序の現在の値マスクを構成します。

  • リモート順序の現在の値マスクを構成します。

  • 非バインド・モードでの現在の順序値を構成します。

図11-1 式エディタの拡張: 順序

図11-1の説明が続きます
「図11-1 式エディタの拡張: 順序」の説明

11.4 ユーザー関数の使用

この項では、ユーザー関数の概要について説明し、Oracle Data Integratorでユーザー関数を作成および使用する方法について説明します。この項では、次の項目について説明します。

11.4.1 ユーザー関数の概要

ユーザー関数を使用すると、マッピングまたはプロシージャで使用できるカスタマイズされた関数を定義できます。同一で複雑な変換パターンを異なるマッピング内の異なるデータストアに割り当てる必要がある場合は、プロジェクトでユーザー関数を使用することをお薦めします。ユーザー関数によって、コードの共有や再利用が促進され、異なるターゲット・プラットフォーム間における開発作業の維持や移植が容易になります。

ユーザー関数は1つ以上のテクノロジに実装され、マッピング、結合、フィルタおよび条件で使用できます。ユーザー関数の使用を参照してください。

関数は、グローバル関数として作成するか、またはプロジェクト内に作成できます。グローバル関数はすべてのプロジェクトに共通で、プロジェクト内の関数はそれが定義されているプロジェクトに関連付けられます。

ユーザー関数は別のユーザー関数を呼び出すことができます。ただし、ユーザー関数がその関数自体を再帰的に呼び出すことはできません。

ノート:

集計関数はユーザー関数でサポートされていません。集計関数コードは作成されますが、GROUP BY式は生成されません。

次の各項では、ユーザー関数を作成および使用する方法について説明します。

11.4.2 ユーザー関数の作成

ユーザー関数を作成するには:

  1. デザイナ・ナビゲータで、プロジェクト内の「ユーザー関数」ノードを選択するか、「グローバル・オブジェクト」ビューの「グローバル・ユーザー関数」ノードを選択します。

  2. 右クリックして「新規ユーザー関数」を選択します。ユーザー関数エディタが開きます。

  3. 次の各フィールドに値を入力します。

    • 名前: ユーザー関数の名前。たとえば、NullValueと指定します。

    • グループ: ユーザー関数のグループ。存在しないグループ名を入力すると、関数の保存時にそのグループ名で新規グループが作成されます。

    • 構文: 式エディタに表示されるユーザー関数の構文。関数の引数はこの構文で指定する必要があります。たとえば、NullValue($(variable), $(default))と指定します。

  4. 「ファイル」メニューから「保存」を選択します。

デザイナ・ナビゲータの「プロジェクト」または「グローバル・オブジェクト」ツリーに関数が表示されます。実装が含まれていないため、まだ使用できません。

実装を作成するには:

  1. デザイナ・ナビゲータで、実装を作成するユーザー関数をダブルクリックします。ユーザー関数エディタが開きます。

  2. ユーザー関数エディタの「実装」タブで「実装の追加」をクリックします。「実装」ダイアログが開きます。

  3. 「実装構文」フィールドに、実装のコードを入力します。たとえば、nvl($(variable), $(default))と入力します。

  4. 実装のリンクされたオブジェクトの各ボックスを選択します。

  5. 新規テクノロジでこの構文を使用する場合は、「新しいテクノロジを自動的に含む」を選択します。

  6. 「OK」をクリックします。

  7. 「ファイル」メニューから「保存」を選択します。

実装を変更するには:

  1. ユーザー関数エディタの「実装」タブで、実装を選択して「編集」をクリックします。

  2. ユーザー関数の「実装」タブで、実装を選択して「実装の編集」をクリックします。「実装」ダイアログが開きます。

  3. この実装の実装構文およびリンクされたテクノロジを変更します。

  4. 新規テクノロジでこの構文を使用する場合は、「新しいテクノロジを自動的に含む」を選択します。

  5. 「OK」をクリックします。

  6. 「ファイル」メニューから「保存」を選択します。

実装を削除するには:

ユーザー関数の「実装」タブで、実装を選択して「実装の削除」をクリックします。

特定のテクノロジでユーザー関数を使用可能にするには:

  1. 特定のテクノロジのテクノロジ・エディタを開きます。
  2. 「言語」列で、テクノロジの言語を選択します。
  3. 「デフォルト」を選択します。
  4. 「定義」タブのテクノロジ・タイプ・リストから対応するテクノロジが選択されていることを確認します。Oracle Data Integrator APIは、ユーザー関数では機能しません。

11.4.3 ユーザー関数の使用

ユーザー関数は、Oracle Data Integratorのすべての式で使用できます。たとえば:

  • コンポーネント属性の「式」プロパティ

  • フィルタ・コンポーネントの「フィルタ条件」プロパティ

  • 結合コンポーネントの「結合条件」プロパティ

ユーザー関数は、その構文を指定して直接使用できます。たとえば、NullValue(CITY_NAME, 'No City')と指定します。

ユーザー関数は、1つ以上のテクノロジに実装されます。たとえば、Oraclenvl(VARIABLE,DEFAULT_VALUE)関数は、VARIABLEまたはDEFAULT_VALUE (VARIABLEがnullの場合)の値を戻しますが、これと同等の関数を持たないテクノロジも存在するため、次の式で置換する必要があります。

case when VARIABLE is null
then DEFAULT_VALUE
else VARIABLE
end

ユーザー関数では、NullValue(VARIABLE,DEFAULT_VALUE)という関数を宣言し、前述の構文に対応する2つの実装を定義できます。実行時に、関数が実行されるテクノロジに応じて、NullValue関数はいずれかの構文で置換されます。

次の例では、様々なテクノロジに応じたコードに変換されるユーザー関数の実装方法を示します。

日付を指定すると月の名前を戻すユーザー関数を定義する場合を考えてみます。この関数は、Oracle、TeradataまたはMicrosoft SQL Serverで実行するときにマッピングで使用できます。表11-6に、この関数をユーザー関数として実装する方法を示します。

表11-6 様々なテクノロジに応じたコードに変換されるユーザー関数(例1)

プロパティ 説明/値

関数名

GET_MONTH_NAME

関数構文

GET_MONTH_NAME($(date_input))

説明

date_inputに指定された日付から月の名前を取得します。

Oracleでの実装

Initcap(to_char($(date_input), 'MONTH'))

Teradataでの実装

case 
	when extract(month from $(date_input)) = 1 then 'January'
	when extract(month from $(date_input)) = 2 then 'February'
	when extract(month from $(date_input)) = 3 then 'March'
	when extract(month from $(date_input)) = 4 then 'April'
	when extract(month from $(date_input)) = 5 then 'May'
	when extract(month from $(date_input)) = 6 then 'June'
	when extract(month from $(date_input)) = 7 then 'July'
	when extract(month from $(date_input)) = 8 then 'August'
	when extract(month from $(date_input)) = 9 then 'September'
	when extract(month from $(date_input)) = 10 then 'October'
	when extract(month from $(date_input)) = 11 then 'November'
	when extract(month from $(date_input)) = 12 then 'December'
end

Microsoft SQLでの実装

datename(month, $(date_input))

これで、属性式、フィルタ条件および結合条件を作成するためにマッピングでこの関数を安全に使用できます。Oracle Data Integratorでは、式の実行場所に応じて適切なコードが生成されます。

様々なテクノロジに応じてコードに変換されるユーザー関数の別の例として、次のマッピングを定義します。

substring(GET_MONTH_NAME(CUSTOMER.LAST_ORDER_DATE), 1, 3)。Oracle Data Integratorでは、実行テクノロジに応じて次のようなコードが生成されます。

表11-7 様々なテクノロジに応じたコードに変換されるユーザー関数(例2)

プロパティ 説明/値

Oracleでの実装

substring(Initcap(to_char(CUSTOMER.LAST_ORDER_DATE 'MONTH')) , 1, 3)

Teradataでの実装

substring(case 	when extract(month from CUSTOMER.LAST_ORDER_DATE) = 1 then 'January'	when extract(month from CUSTOMER.LAST_ORDER_DATE) = 2 then 'February'	...end, 1, 3)

Microsoft SQLでの実装

substring(datename(month, CUSTOMER.LAST_ORDER_DATE) , 1, 3)

関数は、グローバル関数として作成するか、またはプロジェクト内に作成できます。グローバル関数はすべてのプロジェクトに共通で、プロジェクト内の関数はそれが定義されているプロジェクトに関連付けられます。

ユーザー関数は別のユーザー関数を呼び出すことができます。