U moet beslissen of u data_length
. wilt gebruiken of data_precision
gebaseerd op het data_type
, wat u kunt doen met een hoofdletteruitdrukking:
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
/
Als ik die tabel maak als:
create table mytablename (col1 varchar2(20), col2 number(2), col3 char(3), col4 date,
col5 timestamp(3), col6 clob, col7 number(5,2));
dan levert die vraag het volgende op:
COL1,VARCHAR2,20,COL2,NUMBER,2,COL3,CHAR,3,COL4,DATE,,COL5,TIMESTAMP(3),,COL6,CLOB,,COL7,NUMBER,5.2
In dit voorbeeld heb ik een getal weergegeven als precisie .schaal , maar u hoeft zich misschien geen zorgen te maken over schalen, of u wilt ze misschien anders behandelen - hangt af van hoe het resultaat zal worden gebruikt. En ik heb een leeg veld toegevoegd voor de gegevenstypen zonder grootte, b.v. CLOB en DATUM.
Merk ook op dat tijdstempels (en intervallen) de precisie in het gegevenstype zelf bevatten, dus de timestamp(3)
komt rechtstreeks uit het data_type
van die kolom . Tijdstempels met tijdzones en intervallen bevatten ook spaties in de naam van het gegevenstype.
Dit is dus een startpunt en u kunt het uitbreiden naar andere gegevenstypen die u op specifieke manieren moet verwerken, of (laten we zeggen) de precisie van de tijdstempel opsplitsen in een apart door komma's gescheiden veld.