2012-09-01 47 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

相关问题