以table.column格式返回Oracle列名?

FtD*_*Xw6 6 oracle

是否有任何设置或方法可以让Oracle以<table>.<column>格式返回结果?例如:

查询:

SELECT     *
FROM       foo f
INNER JOIN bar b
ON         b.foo_id = f.id
Run Code Online (Sandbox Code Playgroud)

期望的结果:

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
Run Code Online (Sandbox Code Playgroud)

显而易见的解决方案是单独为每列添加别名SELECT f.id AS F_ID, ...; 但是,我需要导出一些非常大的遗留表(300多列),因此使用此方法会导致查询变得庞大且不切实际.

Ben*_*Ben 8

Oracle中没有"选项"可以做到这一点; 您可以找到允许您这样做的客户,因为这是通常在客户端完成的工作; 我不知道一个.

为了扩展tbone的答案,你将不得不动态地做到这一点.这并不意味着您必须列出每一列.您可以使用数据字典,特别是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')
        ;
Run Code Online (Sandbox Code Playgroud)

假设这个表结构:

create table foo ( id number, a number, b number, c number);
create table bar ( foo_id number, a number, b number, c number);
Run Code Online (Sandbox Code Playgroud)

此单个查询生成以下内容:

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
Run Code Online (Sandbox Code Playgroud)

这是一个证明它的SQL小提琴.

在您没有使用11.2时,您可以使用由Tom Kyte创建的未记录的函数wm_concat或用户定义的函数来获得完全相同的结果stragg.Oracle Base有一篇关于字符串聚合技术的文章,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')
        ;
Run Code Online (Sandbox Code Playgroud)

此查询返回:

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
Run Code Online (Sandbox Code Playgroud)