Oracle memiliki fungsi bawaan untuk mendapatkan isi tabel sebagai XML:
create table t42(id number, str varchar2(10));
insert into t42 values (1, 'AA');
insert into t42 values (2, 'BB');
select dbms_xmlgen.getxmltype('select * from t42')
from dual;
DBMS_XMLGEN.GETXMLTYPE('SELECT*FROMT42')
----------------------------------------
<ROWSET>
<ROW>
<ID>1</ID>
<STR>AA</STR>
</ROW>
<ROW>
<ID>2</ID>
<STR>BB</STR>
</ROW>
</ROWSET>
Anda dapat menambahkan tag Anda sendiri di sekitarnya; dapat dilakukan sebagai kueri tetapi karena Anda menginginkan prosedur tersimpan:
create or replace function table_to_xml(table_name in varchar2) return xmltype as
xml xmltype;
begin
select xmlelement("XML",
xmlelement(evalname(table_name),
dbms_xmlgen.getxmltype('select * from "' || table_name || '"')))
into xml
from dual;
return xml;
end table_to_xml;
/
select table_to_xml('T42') from dual;
TABLE_TO_XML('T42')
----------------------------------------
<XML><T42><ROWSET>
<ROW>
<ID>1</ID>
<STR>AA</STR>
</ROW>
<ROW>
<ID>2</ID>
<STR>BB</STR>
</ROW>
</ROWSET>
</T42></XML>
Jadi ini memiliki struktur yang Anda inginkan (ya, saya pikir, tetapi lihat di bawah), tetapi memiliki ROWSET
dan ROW
bukannya RECORDS
dan RECORD
. Itu mungkin tidak masalah, itu tergantung apakah Anda masih mengembangkan format untuk antarmuka ini. Jika itu penting, Anda dapat menerapkan langkah lebih lanjut untuk mengganti nama node tersebut
, atau - lebih bermanfaat - gunakan dbms_xmlgen
prosedur setrowsettag
dan setrowtag
, yang sederhana dalam prosedur Anda (dan ditunjukkan di bawah).
Saya berasumsi apa yang Anda tampilkan sebagai <TABLENAME></TABLENAME>
adalah kesalahan, dan Anda ingin catatan di dalam tag itu. Jika tidak, dan Anda benar-benar menginginkannya karena suatu alasan, ubah kueri dalam fungsi menjadi:
select xmlelement("XML",
xmlconcat(xmlelement(evalname(table_name), null),
dbms_xmlgen.getxmltype('select * from "' || table_name || '"')))
into xml
from dual;
Anda kemudian dapat menuliskannya ke file dengan cara apa pun yang biasa Anda lakukan; jika Anda menelepon dari SQL*Plus dll. Anda dapat memilih dan menggulung, atau jika Anda tidak ingin itu dikembalikan sama sekali, Anda dapat menambahkan UTL_FILE
direktif untuk menulis file dari dalam prosedur, tetapi itu harus ke objek direktori di server DB, yang mungkin tidak nyaman.
Sebagian besar untuk keuntungan saya sendiri karena saya tidak melakukan banyak hal dengan XML:
create or replace procedure table_to_xml_file(table_name in varchar2) as
ctx dbms_xmlgen.ctxhandle;
clb clob;
file utl_file.file_type;
buffer varchar2(32767);
position pls_integer := 1;
chars pls_integer := 32767;
begin
ctx := dbms_xmlgen.newcontext('select * from "' || table_name || '"');
dbms_xmlgen.setrowsettag(ctx, 'RECORDS');
dbms_xmlgen.setrowtag(ctx, 'RECORD');
select xmlserialize(document
xmlelement("XML",
xmlelement(evalname(table_name),
dbms_xmlgen.getxmltype(ctx)))
indent size = 2)
into clb
from dual;
dbms_xmlgen.closecontext(ctx);
file := utl_file.fopen('<directory>', table_name || '.xml', 'w', 32767);
while position < dbms_lob.getlength(clb) loop
dbms_lob.read(clb, chars, position, buffer);
utl_file.put(file, buffer);
utl_file.fflush(file);
position := position + chars;
end loop;
utl_file.fclose(file);
end table_to_xml_file;
/
Saat dijalankan dengan exec table_to_xml_file('T42')
, ini menghasilkan file bernama T42.xml
di direktori server yang ditunjuk oleh <directory>
objek direktori, yang berisi:
<XML>
<T42>
<RECORDS>
<RECORD>
<ID>1</ID>
<STR>AA</STR>
</RECORD>
<RECORD>
<ID>2</ID>
<STR>BB</STR>
</RECORD>
</RECORDS>
</T42>
</XML>
Kebetulan, saya telah menempatkan tanda kutip ganda di sekitar nama tabel di pilih di dalam dbms_xmlgen.getxmltype
panggilan. Itu untuk memenuhi persyaratan 'kasus harus sama seperti di database' untuk nama tabel; itu harus diteruskan ke prosedur dalam kasus yang benar atau akan salah. Itu lebih sederhana daripada mencoba memperbaiki kasing dalam prosedur entah bagaimana, yang akan canggung, atau tidak mungkin jika Anda memiliki dua tabel dengan nama yang sama selain kasing. Nama kolom akan tetap dalam huruf yang benar.