2012-09-01 76 views
6

是否有任何設置或方法可用於讓Oracle以<table>.<column>格式返回結果?例如:以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列),所以使用這種方法會導致查詢是巨大的和不切實際的。

+0

İ'm在PL/SQL無法勝任的,但也許你可以嘗試加入他們之前,重命名錶中的列。 – bonsvr

+0

您如何導出數據?也許這個邏輯屬於那個導出工具,而不是單個的語句? –

回答

8

在Oracle中沒有「選項」來執行此操作;你可能能夠找到一個客戶端,允許你這樣做,因爲這是通常在客戶端完成的工作;我不知道一個。

要擴大tbone's answer你將不得不動態做到這一點。這意味着你必須列出每一列。您將使用data dictionary,特別是all_tab_columnsuser_tab_columns來創建您的查詢。用您想要的確切定義創建視圖會更容易,以便您可以重新使用它。

目的是使用列存在作爲字符串存儲在表中的事實,以便創建查詢以使用該列。由於列名稱和表名稱以字符串形式存儲,因此您可以使用字符串聚合技術輕鬆創建查詢或DDL語句,然後您可以手動或動態執行。

如果你使用的是Oracle 11g第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); 

這種單一的查詢將產生以下:

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或用戶定義函數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

使用別名不會使查詢變得不切實際,它只是不如打字*方便。使用動態SQL生成欄目爲您提供:

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

做其它任何你需要寬表相同,並複製/粘貼到您的查詢。還要注意30個字符的限制,希望您的所有列都不超過28個。

+0

謝謝你的建議,但我特別要求一個不涉及明確列出列的解決方案。 – FtDRbwLXw6

相關問題