Anda perlu memutuskan apakah akan menggunakan data_length
atau data_precision
berdasarkan data_type
, yang dapat Anda lakukan dengan ekspresi kasus:
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
/
Jika saya membuat tabel itu sebagai:
create table mytablename (col1 varchar2(20), col2 number(2), col3 char(3), col4 date,
col5 timestamp(3), col6 clob, col7 number(5,2));
maka kueri itu menghasilkan:
COL1,VARCHAR2,20,COL2,NUMBER,2,COL3,CHAR,3,COL4,DATE,,COL5,TIMESTAMP(3),,COL6,CLOB,,COL7,NUMBER,5.2
Dalam contoh ini saya telah mewakili angka sebagai presisi .skala , tetapi Anda mungkin tidak perlu khawatir dengan timbangan, atau mungkin ingin menanganinya secara berbeda - tergantung bagaimana hasilnya akan digunakan. Dan saya telah menyertakan bidang kosong untuk tipe data tanpa ukuran, mis. CLOB dan DATE.
Perhatikan juga bahwa stempel waktu (dan interval) menyertakan presisi dalam tipe data itu sendiri, jadi timestamp(3)
datang langsung dari data_type
kolom itu . Stempel waktu dengan zona waktu dan interval juga menyertakan spasi dalam nama tipe data.
Jadi ini adalah titik awal, dan Anda dapat memperluasnya ke tipe data lain yang perlu Anda tangani dengan cara tertentu, atau (misalnya) membagi presisi stempel waktu menjadi bidang terpisah yang dipisahkan koma.