2012-09-01 5 views
6

Oracleに結果を<table>.<column>形式で返すために使用できる設定や方法はありますか?例えば:Oracleの列名をtable.column形式で戻しますか?

クエリ:

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+カラム)をエクスポートする必要があるため、このメソッドを使用するとクエリが膨大かつ非実用的になります。

+0

- 私PL/SQLで有能、おそらくあなたがそれらに参加する前に、テーブルの列の名前を変更しようとするかもしれません。 – bonsvr

+0

どのようにデータをエクスポートしていますか?たぶん、このロジックは、個々のステートメントの代わりにそのエクスポートツールに属しているのでしょうか? –

答えて

8

これには、Oracleではオプションがありません。 これは通常、クライアントで行われるジョブであるため、これを可能にするクライアントを見つけることができます。私は1つを知らない。

tbone's answerに拡張するには、これを動的に行う必要があります。このではありません。すべての列をリストする必要があります。 data dictionary、具体的にはall_tab_columnsまたはuser_tab_columnsを使用してクエリを作成します。必要な場合に再利用できるように、正確な定義を持つビューを作成する方が簡単です。

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

あなたはlistagg機能2 Oracle 11gのリリースを使用している場合はあなたを助けるために提供されています:

このテーブル構造を仮定し
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); 

は、この単一のクエリは、次を生成します。

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を使用していない場合は、文書化されていない関数wm_concatまたはTom Kyteによって作成されたユーザー定義関数straggを使用して、全く同じ結果を得ることができます。 Oracle Baseにはstring aggregation techniquesに関する記事があり、Stack Overflowに関する記事が多数あります。

少しの補足として、上記のクエリを少し変更するだけで、実際にあなたが探しているものを正確に作成することができます。 quoted identifierを使用して、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') 
     ; 

This query returns

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 
3

エイリアスを使用してもクエリを実行することはできません。*と入力するほど便利ではありません。

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

必要な他のワイド・テーブルでも同じことを行い、クエリにコピー/ペーストします。また、30文字の制限に注意してください。あなたの列のサイズが28を超えていないことを願ってください。

+0

提案をいただきありがとうございますが、明示的に列を列挙しないような解決策を具体的に求めていました。 – FtDRbwLXw6

関連する問題