私はPL/SQLコードを書いて、テーブルを非正規化し、クエリを実行しやすい形式にしました。このコードでは、一時テーブルを使用して作業の一部を実行し、元のテーブルのいくつかの行を一緒にマージします。
ロジックは、リンクされた記事のパターンに従って、パイプライン化されたテーブル関数として記述されます。表関数は、PRAGMA AUTONOMOUS_TRANSACTION
宣言を使用して一時表操作を許可し、カーソル入力パラメーターを受け入れて非正規化を特定の ID 値に制限します。
次に、テーブル関数をクエリするためのビューを作成し、考えられるすべての ID 値をカーソルとして渡します (関数の他の使用法はより制限されます)。
私の質問: これは本当に必要ですか? 同じことを達成するためのはるかに簡単な方法を完全に見逃していませんか?
PL/SQL に触れるたびに、入力しすぎているような印象を受けます。
更新:私が扱っているテーブルのスケッチを追加して、私が話している非正規化のアイデアをすべての人に提供します。このテーブルには、従業員の仕事の履歴が格納され、それぞれにアクティブ化行と (場合によっては) 終了行があります。従業員が複数の仕事を同時に持つことも、連続していない日付範囲で何度も同じ仕事をすることも可能です。例えば:
| EMP_ID | JOB_ID | STATUS | EFF_DATE | other columns...
| 1 | 10 | A | 10-JAN-2008 |
| 2 | 11 | A | 13-JAN-2008 |
| 1 | 12 | A | 20-JAN-2008 |
| 2 | 11 | T | 01-FEB-2008 |
| 1 | 10 | T | 02-FEB-2008 |
| 2 | 11 | A | 20-FEB-2008 |
それを照会して、誰がいつどの仕事で働いているかを把握することは自明ではありません。EMP_ID
したがって、私の非正規化関数は、カーソルを介して渡されたすべての s について、各ジョブの日付範囲のみを一時テーブルに入力します。s 1 と 2 を渡すEMP_ID
と、次のようになります。
| EMP_ID | JOB_ID | START_DATE | END_DATE |
| 1 | 10 | 10-JAN-2008 | 02-FEB-2008 |
| 2 | 11 | 13-JAN-2008 | 01-FEB-2008 |
| 1 | 12 | 20-JAN-2008 | |
| 2 | 11 | 20-FEB-2008 | |
(終了日が事前に決められていないジョブの をEND_DATE
許可します。)NULL
ご想像のとおり、この非正規化形式はクエリがはるかに簡単ですが、それを作成するには (私が知る限りでは) 中間結果 (たとえば、アクティベーション行が実行されたジョブ レコード) を格納するための一時テーブルが必要です。見つかりましたが、終了ではありません...まだ)。パイプライン化されたテーブル関数を使用して一時テーブルにデータを入力し、その行を返すことは、私がその方法を理解した唯一の方法です。