Oracle
 sql >> Database >  >> RDS >> Oracle

Recupero della struttura della tabella con SQL dinamico

Devi decidere se usare data_length o data_precision in base al data_type , che puoi eseguire con un'espressione 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 creo quella tabella come:

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

quindi quella query produce:

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

In questo esempio ho rappresentato un numero come precisione .scala , ma potresti non avere le scale di cui preoccuparti o potresti volerle gestire in modo diverso, dipende da come verrà utilizzato il risultato. E ho incluso un campo vuoto per i tipi di dati senza dimensioni, ad es. CLOB e DATA.

Nota inoltre che i timestamp (e gli intervalli) includono la precisione nel tipo di dati stesso, quindi il timestamp(3) proviene direttamente dal data_type di quella colonna . I timestamp con fusi orari e intervalli includono anche spazi nel nome del tipo di dati.

Quindi questo è un punto di partenza e puoi estenderlo ad altri tipi di dati che devi gestire in modi specifici o (ad esempio) suddividere la precisione del timestamp in un campo separato da virgole.