0

レポート対象のデータに基づいてテーブルを作成する必要があるストアド プロシージャを作成しています。

この状況では、ある日付範囲の特定のコードについて、1 日あたり 3 つの値を取得します。

このストアド プロシージャの特定の実行で、日付範囲のコード値 X、Y、および Z があるとします。

select abc.code, 
       abc.date, 
       abc.val_1, 
       abc.val_2, 
       abc.val_3
  from data.abc
 where abc.date BETWEEN '01-OCT-2009' AND '31-OCT-2009'

したがって、日付範囲の各日について、コード x、y、および z の 3 つのレコードがあります。

最終的なテーブルでは、これを行から列に変換する必要があります。通常はデコード関数を使用しますが、ここでは、戻ってくるデータに基づいて最終テーブルを動的に作成したいと考えています。

この場合、範囲内の日ごとに 1 つのレコードがあり、さらに 9 つの列 (val_1_X、val_2_x、val_3_x、val_1_y など) があります。

これを動的に設定して、新しい「コード」が導入されたときにストアド プロシージャを再度開く必要がないようにし、レポートの各インスタンスで、そのインスタンスで「コード」のみが返されるようにします。レポートは最終表に含まれています。

これは動的SQLで可能ですか? 私は Oracle バージョン 10g を使用しています。

4

3 に答える 3

1

私の理解では、2009 年 10 月 1 日から 2009 年 10 月 31 日まではコードxy、およびzしかありませんが、2009 年 11 月 30 日まではwになる可能性があります。

最終的には、次のようなクエリが必要です。

CREATE TABLE t1 AS
  SELECT
    abc.date,
    MAX(DECODE(code, 'x', val_1, NULL)) AS abc_val_1_x,
    MAX(DECODE(code, 'x', val_2, NULL)) AS abc_val_2_x,
    MAX(DECODE(code, 'x', val_3, NULL)) AS abc_val_3_x,
    MAX(DECODE(code, 'y', val_1, NULL)) AS abc_val_1_y,
    MAX(DECODE(code, 'y', val_2, NULL)) AS abc_val_2_y,
    MAX(DECODE(code, 'y', val_3, NULL)) AS abc_val_3_y,
    ...
  FROM data.abc
  WHERE abc.date BETWEEN '01-OCT-2009' AND '31-OCT-2009'
  GROUP BY abc.date

私は Oracle の専門家ではなく、Oracle でのテストにアクセスできないため、以下にかなりの数の構文エラーなどを見つけることができます。また、ハードコードされた日付を変数に変更し、いくつかの変数を宣言して、作成したクエリを実際に実行する必要があります。

-- Figure out all valid codes for date range.
-- Might also require ordering depending on your report.
CURSOR c1
  IS
    SELECT
      abc.code
    FROM data.abc
    WHERE abc.date BETWEEN '01-OCT-2009' AND '31-OCT-2009'
    GROUP BY abc.code;

query1 := 'CREATE TABLE abc_report AS SELECT date';
LOOP
    FETCH c1 INTO code1
    EXIT WHEN c1%NOTFOUND;
    query1 := query1 || ', DECODE(code, ''' || code1 || ''', val_1, NULL)) AS abc_val_1_' || code1 ||
        ', DECODE(code, ''' || code1 || ''', val_2, NULL)) AS abc_val_2_' || code1 ||
        ', DECODE(code, ''' || code1 || ''', val_3, NULL)) AS abc_val_3_' || code1
END LOOP;
query1 := query1 || ' FROM data.abc WHERE date BETWEEN ''01-OCT-2009'' AND ''31-OCT-2009'''
于 2009-11-04T06:19:54.420 に答える
0

助けてくれてどうもありがとう。ストアド プロシージャは開始され、レポート ツールによって使用される予定でした。このレポートの複数のインスタンスが同時に実行される可能性に備える必要があるため、テーブル名を再利用することはできません。各実行インスタンスに固有のテーブルを作成するストアド プロシージャを使用することはできません。

それでも助けてくれてありがとう!

于 2009-11-04T15:39:05.467 に答える