Oracle има вградена функция за получаване на съдържанието на таблица като 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>
Можете да добавите свои собствени тагове около това; може да се направи като заявка, но тъй като искате съхранена процедура:
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>
Така че това има структурата, която искате (добре, мисля, но вижте по-долу), но има ROWSET
и ROW
вместо RECORDS
и RECORD
. Това може няма значение, зависи дали все още разработвате формата за този интерфейс. Ако има значение, можете да приложите допълнителна стъпка за преименуване на тези възли
, или - по-полезно - използвайте dbms_xmlgen
процедури setrowsettag
и setrowtag
, което е просто във вашата процедура (и демонстрирано по-долу).
Предполагам, че сте показали като <TABLENAME></TABLENAME>
беше грешка и искате записите в този етикет. Ако не, и наистина искате това по някаква причина, променете заявката във функцията на:
select xmlelement("XML",
xmlconcat(xmlelement(evalname(table_name), null),
dbms_xmlgen.getxmltype('select * from "' || table_name || '"')))
into xml
from dual;
След това можете да запишете това във файл по всеки обичаен начин; ако се обаждате от SQL*Plus и т.н., можете да изберете и спулирате, или ако изобщо не искате да се връща, можете да добавите UTL_FILE
директива за запис на файла от процедурата, но това трябва да бъде в обект на директория на DB сървъра, което може да не е удобно.
Предимно за моя собствена полза, тъй като не правя много с 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;
/
Когато се изпълнява с exec table_to_xml_file('T42')
, това създава файл, наречен T42.xml
в директорията на сървъра, към която сочи <directory>
обект на директория, който съдържа:
<XML>
<T42>
<RECORDS>
<RECORD>
<ID>1</ID>
<STR>AA</STR>
</RECORD>
<RECORD>
<ID>2</ID>
<STR>BB</STR>
</RECORD>
</RECORDS>
</T42>
</XML>
Между другото, поставих двойни кавички около името на таблицата в селекцията вътре в dbms_xmlgen.getxmltype
повикване. Това е, за да се отговори на изискването „регистрът трябва да е същият като в базата данни“ за името на таблицата; трябва да се предаде на процедурата в правилния случай или ще се появи грешка. Това е по-просто, отколкото да се опитвате някак да коригирате случая в рамките на процедурата, което би било неудобно или невъзможно, ако имате две таблици с едно и също име, освен случая. Имената на колоните така или иначе ще бъдат в правилния регистър.