2012-09-01 17 views
6

¿Hay alguna configuración o método que pueda usar para que Oracle devuelva resultados en el formato <table>.<column>? Por ejemplo:¿Devuelve los nombres de columna de Oracle en formato table.column?

Consulta:

SELECT  * 
FROM  foo f 
INNER JOIN bar b 
ON   b.foo_id = f.id 

resultados deseados:

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 

La solución obvia es individualmente alias cada columna SELECT f.id AS F_ID, ...; sin embargo, necesito exportar algunas tablas heredadas muy grandes (más de 300 columnas), por lo que usar este método haría que las consultas fueran enormes y poco prácticas.

+0

no soy competente en PL/SQL, pero tal vez usted puede tratar de cambiar el nombre de las columnas de las tablas antes de unirse a ellos. – bonsvr

+0

¿Cómo está exportando los datos? ¿Tal vez esta lógica pertenece a esa herramienta de exportación, en lugar de las declaraciones individuales? –

Respuesta

8

No hay una "opción" en Oracle para hacer esto; usted puede podrá encontrar un cliente que le permita hacerlo ya que este es un trabajo que normalmente se haría en el cliente; No sé de uno. Para ampliar tbone's answer, tendrá que hacer esto de forma dinámica. Esto no significa significa que debe listar cada columna. Utilizaría el data dictionary, específicamente all_tab_columns o user_tab_columns para crear su consulta. Sería más fácil crear una vista con la definición exacta que desea para que pueda volver a utilizarla si lo desea.

El objetivo es utilizar el hecho de que la existencia de columnas se almacena en una tabla como una cadena para crear una consulta para usar esa columna. Como los nombres de las columnas y de las tablas se almacenan como cadenas, puede usar técnicas de agregación de cadenas para crear fácilmente una consulta o una declaración DDL que luego puede ejecutar de forma manual o dinámica.

Si está utilizando Oracle 11g Release 2 listagg la función está disponible para ayudarle a:

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') 
     ; 

Suponiendo que esta estructura de la tabla:

create table foo (id number, a number, b number, c number); 
create table bar (foo_id number, a number, b number, c number); 

Esta sola consulta produce lo siguiente:

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 

y aquí hay un SQL Fiddle para demostrarlo.

En el que no está utilizando 11.2 puede obtener exactamente los mismos resultados utilizando la función no documentada wm_concat o la función definida por el usuario stragg, que fue creada por Tom Kyte. Oracle Base tiene un artículo en string aggregation techniques y hay muchas publicaciones en Stack Overflow.

Como un pequeño apéndice, puede crear exactamente lo que está buscando con un pequeño cambio a la consulta anterior. Puede usar un quoted identifier para crear una columna en el formato TABLE_NAME.COLUMN_NAME.Usted tiene para citarlo como . no es un carácter válido para un nombre de objeto en Oracle. El beneficio de esto es que obtienes exactamente lo que quieres. La desventaja es que consultar la vista creada es un gran dolor si no usas select * from ...; al seleccionar las columnas con nombre se requieren para ser cotizadas.

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

El uso de alias no haría que las consultas se vuelvan poco prácticas, simplemente no es tan conveniente como escribir *. Utilizar SQL dinámico para generar las columnas para usted:

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

hacer lo mismo para cualquier otra tabla de ancho que necesita, y copiar/pegar en su consulta. También tenga en cuenta el límite de 30 caracteres, ojalá ninguna de sus columnas tenga más de 28.

+0

Gracias por la sugerencia, pero específicamente pedí una solución que no implique enumerar explícitamente las columnas. – FtDRbwLXw6

Cuestiones relacionadas