6

<table>.<column>Oracle に結果をフォーマットで返させるために使用できる設定または方法はありますか? 例えば:

クエリ:

SELECT     *
FROM       foo f
INNER JOIN bar b
ON         b.foo_id = f.id

望ましい結果:

F.ID  F.BLAH  B.ID  B.FOO_ID  B.BLAH
--------------------------------------------------------
1     blah    7     1         blah
2     blah    8     2         blah
3     blah    9     2         blah

明らかな解決策は、各列に個別にエイリアスを設定することSELECT f.id AS F_ID, ...です。ただし、非常に大きなレガシー テーブル (300 列以上) をエクスポートする必要があるため、この方法を使用するとクエリが膨大になり、実用的ではなくなります。

4

2 に答える 2

8

これを行うための「オプション」は Oracle にはありません。これは通常クライアントで実行されるジョブであるため、これを可能にするクライアントを見つけることができる場合があります私は一つも知りません。

tbone の回答を拡張するには、これを動的に行う必要があります。これは、すべての列をリストする必要があるという意味ではありません。データ ディクショナリ、具体的にはall_tab_columnsを使用するかuser_tab_columns、クエリを作成します。必要に応じて再利用できるように、必要な正確な定義でビューを作成する方が簡単です。

目的は、その列を使用するクエリを作成するために、列の存在が文字列としてテーブルに格納されているという事実を使用することです。列名とテーブル名は文字列として格納されるため、文字列集計手法を使用して、手動または動的に実行できるクエリまたは DDL ステートメントを簡単に作成できます。

Oracle 11g Release 2 を使用している場合は、次のlistagg機能を利用できます。

select 'create or replace view my_view as 
        select '
      || listagg( table_name || '.' || column_name 
               || ' as ' 
               || substr(table_name,1,1) || '_' 
               || column_name, ', ')
        within group 
         ( order by case when table_name = 'FOO' then 0 else 1 end
                  , column_id
          )
       || ' from foo f
            join bar b
              on f.id = b.foo_id'
  from user_tab_columns
 where table_name in ('FOO','BAR')
        ;

次のテーブル構造を想定します。

create table foo ( id number, a number, b number, c number);
create table bar ( foo_id number, a number, b number, c number);

この 1 つのクエリで次の結果が生成されます。

create or replace view my_view as 
 select FOO.ID as F_ID, FOO.A as F_A, FOO.B as F_B, FOO.C as F_C
      , BAR.FOO_ID as B_FOO_ID, BAR.A as B_A, BAR.B as B_B, BAR.C as B_C 
   from foo f 
   join bar b on f.id = b.foo_id

これを証明するSQL Fiddleがあります。

11.2 を使用していない場合は、文書化されていない関数またはTom Kyte によって作成されwm_concatたユーザー定義関数を使用して、まったく同じ結果を得ることができます。Oracle Base には文字列集計手法straggに関する記事があり、Stack Overflow には多くの投稿があります。

ちょっとした補遺として、上記のクエリを少し変更するだけで、実際に探しているものを正確に作成できます。引用符付き識別子を使用して、TABLE_NAME.COLUMN_NAMEフォーマットで列を作成できます。Oracle ではオブジェクト名として有効な文字ではないため、引用符で囲む必要があります。.これの利点は、あなたが望むものを正確に得ることです。欠点は、作成されたビューをクエリするのは、使用しないと非常に面倒なことですselect * from ...。名前付き列を選択するには、それらを引用する必要があります。

select 'create or replace view my_view as
        select '
      || listagg( table_name || '.' || column_name 
               || ' as ' 
               || '"' || table_name || '.'
               || column_name || '"', ', ')
        within group 
         ( order by case when table_name = 'FOO' then 0 else 1 end
                  , column_id
          )
       || ' from foo f
            join bar b
              on f.id = b.foo_id'
  from user_tab_columns
 where table_name in ('FOO','BAR')
        ;

このクエリは次を返します

create or replace view my_view as 
 select FOO.ID as "FOO.ID", FOO.A as "FOO.A", FOO.B as "FOO.B", FOO.C as "FOO.C"
      , BAR.FOO_ID as "BAR.FOO_ID", BAR.A as "BAR.A"
      , BAR.B as "BAR.B", BAR.C as "BAR.C"
   from foo f 
   join bar b on f.id = b.foo_id
于 2012-09-02T09:43:33.483 に答える
3

エイリアスを使用しても、クエリが実用的でなくなることはありません。*を入力するほど便利ではありません。動的SQLを使用して、列を生成します。

select 'f.' || column_name || ' as F_' || column_name || ','
from all_tab_columns
where table_name = 'FOO'
order by column_id;

必要な他の幅の広いテーブルについても同じことを行い、クエリにコピーして貼り付けます。また、30文字の制限にも注意してください。うまくいけば、どの列もサイズが28を超えないようにしてください。

于 2012-09-01T19:34:58.267 に答える