sql >> Base de Datos >  >> RDS >> Oracle

Recuperación de la estructura de la tabla con SQL dinámico

Debe decidir si usar data_length o data_precision basado en el data_type , lo que puede hacer con una expresión de mayúsculas y minúsculas:

select listagg(column_name ||','|| data_type ||','||
  case 
    when data_type in ('VARCHAR2', 'NVARCHAR2', 'CHAR', 'RAW')
      then to_char(data_length)
    when data_type = 'NUMBER'
        and (data_precision is not null or data_scale is not null)
      then data_precision || case
        when data_scale > 0 then '.' || data_scale
      end
    end, ',') within group (order by column_id)
from all_tab_columns
where table_name = 'MYTABLENAME'
and owner = user -- if it is always current user, use user_tab_columns instead
/

Si creo esa tabla como:

create table mytablename (col1 varchar2(20), col2 number(2), col3 char(3), col4 date,
  col5 timestamp(3), col6 clob, col7 number(5,2));

entonces esa consulta produce:

COL1,VARCHAR2,20,COL2,NUMBER,2,COL3,CHAR,3,COL4,DATE,,COL5,TIMESTAMP(3),,COL6,CLOB,,COL7,NUMBER,5.2

En este ejemplo he representado un número como precisión .escala , pero es posible que no tenga que preocuparse por las escalas, o que desee manejarlas de manera diferente; depende de cómo se usará el resultado. Y he incluido un campo vacío para los tipos de datos sin tamaño, p. CLOB y FECHA.

También tenga en cuenta que las marcas de tiempo (e intervalos) incluyen la precisión en el tipo de datos en sí, por lo que timestamp(3) proviene directamente del data_type de esa columna . Las marcas de tiempo con zonas horarias e intervalos también incluyen espacios en el nombre del tipo de datos.

Así que este es un punto de partida, y puede extenderlo a otros tipos de datos que necesita manejar de maneras específicas, o (digamos) dividir la precisión de la marca de tiempo en un campo separado separado por comas.