参加するAMP vprocは、SELECT文でテーブル関数の前に指定されている相関テーブル名から関数に提供される入力データに関連する行を含んでいます。この場合の前提は、入力引数によって処理対象が決定されるということです。関数の各コピーは、それ以上のデータがないという条件を示して関数が戻るまで、同じ入力データで繰り返し呼び出されます。
このモードでデータベースの外部から追加のデータを読み取ることも場合によっては可能ですが、通常は機能しません。これは、選択対象のデータベース行がどこに存在するかに基づいて、参加するAMP vprocが決定されるためです。すべてのAMP vprocにデータが存在するとは限りません。
ガイドラインとして以下のコード抜粋を使用してFNC_GetPhaseを用いた関数を実装します。
typedef struct { scratch_XML xml_ctx; } local_ctx; FNC_Phase Phase; local_ctx *state_info; if ( FNC_GetPhase(& Phase) != TBL_MODE_VARY) { /* Set sqlstate to an error and return. */ strcpy(sqlstate, "U0005"); return; } /* depending on the phase decide what to do */ switch(Phase) { case TBL_PRE_INIT: { /* Allocate scratchpad to retain data between iterations. */ state_info = FNC_TblAllocCtx(sizeof(local_ctx)); break; } case TBL_INIT: { /* Get scratchpad. */ state_info = FNC_TblGetCtx; /* Preprocess data here. */ ... break; } case TBL_BUILD: { /* Get scratchpad and build the result row here. */ state_info = FNC_TblGetCtx; ... /* Or, if no more rows to build, set sqlstate to "02000". */ strcpy(sqlstate, "02000"); ... break; } case TBL_FINI: { /* Reset for the next set of data. */ state_info = FNC_TblGetCtx; ... break; } case TBL_END: { /* Everyone done. */ ... break; } }
使用するテーブル関数が関数を実行しているAMP上のすべての入力ローを受け取るまで結果ローを作成しない場合は、FNC_GetPhaseの代わりにFNC_GetPhaseExとTBL_LASTROWオプションを使用できます。これは、TBL_BUILD_EOFフェーズで行を作成します。ガイドラインとして以下のコード抜粋を使用してFNC_GetPhaseExを用いた関数を実装します。
typedef struct { scratch_XML xml_ctx; } local_ctx; FNC_Phase Phase; local_ctx *state_info; if ( FNC_GetPhaseEx(& Phase, TBL_LASTROW) != TBL_MODE_VARY) { /* Set sqlstate to an error and return. */ strcpy(sqlstate, "U0005"); return; } /* depending on the phase decide what to do */ switch(Phase) { case TBL_PRE_INIT: { /* Allocate scratchpad to retain data between iterations. */ state_info = FNC_TblAllocCtx(sizeof(local_ctx)); break; } case TBL_INIT: { /* Get scratchpad. */ state_info = FNC_TblGetCtx; /* Preprocess data here. */ ... break; } case TBL_BUILD: { /* Get scratchpad and add data here. */ state_info = FNC_TblGetCtx; ... /* Set sqlstate to "02000" to indicate not to output rwsult rows here. */ strcpy(sqlstate, "02000"); ... break; } case TBL_BUILD_EOF: { /* Get scratchpad and build result row here. */ state_info = FNC_TblGetCtx; ... /* Or, if no more rows to build, set sqlstate to "02000". */ strcpy(sqlstate, "02000"); ... break; } case TBL_FINI: { /* Reset for the next set of data. */ state_info = FNC_TblGetCtx; ... break; } case TBL_END: { /* Everyone done. */ ... break; } }
テーブル関数の呼び出しごとに新しいローを取得する必要がある場合は、TBL_NEWROWオプションを指定したFNC_GetPhaseExを使用します。次に示すコードの抜粋は、これの使用例です。
{ FNC_Phase Phase; /* Make sure the function is called in the supported context. */ /* Only ask for the phase on each row. */ switch (FNC_GetPhaseEx(&Phase, TBL_NOOPTIONS)) { case TBL_MODE_CONST: strcpy(sqlstate, "U0005"); strcpy((char *) errormsg, "Table function being called in unsupported mode."); return; case TBL_MODE_VARY: switch(Phase) { case TBL_PRE_INIT: /* Ask for a new row on each call to build */ FNC_GetPhaseEx(&Phase,TBL_NEWROW); break; case TBL_INIT: break; case TBL_BUILD: *out1 = *in1; strcpy((char*)out2,(char*)in2); break; case TBL_FINI: break; case TBL_END: break; } break; } }
上記のサンプル コードは、単に入力引数の値を出力列として返しているだけです。そのため、UDFテーブルの反復実行間でステータス情報を維持する、コンテキスト オブジェクトは必要ありません。テーブルUDFの反復実行間でステータス情報を維持するために、コンテキスト オブジェクトが必要なときには、適切なフェーズでコンテキスト オブジェクトを定義、割り当て、設定および取得するコードを必要に応じて組み込む必要があります。