Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Recuperando a Estrutura da Tabela com SQL Dinâmico


Você precisa decidir se deve usar data_length ou data_precision com base no data_type , que você pode fazer com uma expressão case:
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
/

Se eu criar essa tabela como:
create table mytablename (col1 varchar2(20), col2 number(2), col3 char(3), col4 date,
  col5 timestamp(3), col6 clob, col7 number(5,2));

então essa consulta produz:
COL1,VARCHAR2,20,COL2,NUMBER,2,COL3,CHAR,3,COL4,DATE,,COL5,TIMESTAMP(3),,COL6,CLOB,,COL7,NUMBER,5.2

Neste exemplo, representei um número como precisão .escala , mas você pode não ter escalas para se preocupar, ou pode querer tratá-las de forma diferente - depende de como o resultado será usado. E incluí um campo vazio para os tipos de dados sem tamanho, por exemplo CLOB e DATA.

Observe também que os timestamps (e intervalos) incluem a precisão no próprio tipo de dados, então o timestamp(3) está vindo diretamente do data_type dessa coluna . Os carimbos de data/hora com fusos horários e intervalos também incluem espaços no nome do tipo de dados.

Portanto, este é um ponto de partida e você pode estendê-lo para outros tipos de dados que precisa manipular de maneiras específicas ou (digamos) dividir a precisão do carimbo de data/hora em um campo separado por vírgulas.