2016-08-08 17 views
-1

OracleデータベースでSQLを使用しています。別のプログラムで分析するためにデータを抽出するために必要なテーブルがいくつかあります。私はこのプロセスを効率的に実装しようとしています。複数のテーブルの内容を出力する

最終生成物は.CSV形式ファイル、たとえば次のようになります。これらのクエリを使用して

TableName1, Data1, Data2, Data3 
TableName1, Data1, Data2, Data3 
TableName2, Data1, Data2, Data3, Data4 
TableName2, Data1, Data2, Data3, Data4 
TableName3, Data1, Data2 

など

私はそれを使用することができますので、私は私が必要とするデータとフィールドの数を取得しますforループ可能に:私は失われています

SELECT * FROM MY_TABLE_NAME 
    SELECT count(column_name) FROM all_tab_cols WHERE table_name = 'MY_TABLE_NAME' 

はかかわらず、ブロックにこれを変換する方法です。将来このコードを実行する必要があるので、必要に応じて後でテーブルを追加したり削除したりすることができるように、最初は配列を各テーブルの名前で記述することができます。各テーブルには、フィールドごとに異なる数のフィールドとデータ型もあります。私が今まで試みてきたアプローチはすべて、DEFINEブロックにこれらのそれぞれを明示的に記述する必要がありますが、これは実現不可能です。これらのデータセットを動的にループする最良の方法は何ですか?

誰かが次にどこへ向かうべき正しい方向に向けることができますか?

答えて

2

ループ(またはプロシージャとPL/SQLに関係するもの)を記述する必要はありません。あなたが必要とするのは、2つのことです:あなたが含むべきテーブルの名前を持つテーブル(あなたが言ったように、これは時間の経過とともに変化するかもしれません - テーブルのセットのための最良の場所はテーブルです)とクエリ。 I以下の溶液で

モックテーブルを作成し(with句で)最初の因数分解サブクエリの列tntable_namesと呼ばれます。実生活では、そのCTEを削除し、実際の表と列名を使用してください。 LISTAGGの列は、SELECT *COLUMN_IDUSER_TAB_COLUMNSで示される)に表示される順序で集計されます。

これは、SCOTTスキーマの表でこれを示しています。 table_namesのテーブルにスキーマに存在しないテーブルが含まれていると、何が起こるのかを確認します。結果の文字列にはテーブル名、カンマとスペース、その他は表示されません。これはOUTER JOINの結果です。そのような存在しないテーブルを含めたくない場合は、それをINNER JOINに変更することができます。 (また、最初にすべてのテーブル名が実際に存在するスキーマに存在するかどうかを確認するために別のクエリを書くこともできます)。

これは、異なる所有者/スキーマ間で動作するようにも書かれていません。それがあなたが必要とするものならば、それは簡単に適合させることができます。特に、USER_TAB_COLUMNSの代わりにALL_TAB_COLUMNSを使用します。

クエリ

with table_names (tn) as (
     select 'PINOCCHIO' from dual union all 
     select 'EMAIL_ADDRESSES' from dual union all 
     select 'BONUS'   from dual union all 
     select 'ORDER_ITEM'  from dual 
    ) 
select t.tn, t.tn || ', ' || listagg(c.column_name, ', ') 
            within group (order by c.column_id) as str 
from table_names t left outer join user_tab_columns c 
       on t.tn = c.table_name 
group by tn 
; 

出力

(Iは、ユーザーSCOTTとして接続しています、覚えて - オラクルDBのいずれかのインストール中にデフォルトで存在する標準スキーマ...

TN    STR 
--------------- ---------------------------------------------------------- 
BONUS   BONUS, ENAME, JOB, SAL, COMM 
EMAIL_ADDRESSES EMAIL_ADDRESSES, INTERNET_ADDRESS_ID, EMAIL_ADDRESS 
ORDER_ITEM  ORDER_ITEM, ORDER_ID, ITEM_ID, QTY 
PINOCCHIO  PINOCCHIO, 

4 rows selected. 
+0

フィールド名の列を取得し、それらを連結するためのチャンピオンのように機能します。パスワードは「tiger」です。しかし、私はそれをアルファベット順に並べ替えるように見えます。どのように構造を維持するのですか?たとえば、自分のフィールドが 'B'、 'C​​'、 'A'のようにレイアウトされている場合、それらをLISTAGGで 'A、B、C'にどのように並べ替えるのですか? – SandPiper

+0

アルファベット順ではありません(BONUSテーブルの最後のものとしてCOMMを参照してください)。私は答えて説明しました:注文は、USER_TAB_COLUMNSテーブルのCOLUMN_IDによるものです。 SELECT * FROM 文を実行した場合に表示される順序と同じです。 – mathguy

+0

ああ!私はその行を逃した、私の謝罪。ありがとう、チャンピオンのように働いた。 – SandPiper

関連する問題