Oracle
 sql >> база данни >  >> RDS >> Oracle

генерира XML от таблици на oracle

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 повикване. Това е, за да се отговори на изискването „регистрът трябва да е същият като в базата данни“ за името на таблицата; трябва да се предаде на процедурата в правилния случай или ще се появи грешка. Това е по-просто, отколкото да се опитвате някак да коригирате случая в рамките на процедурата, което би било неудобно или невъзможно, ако имате две таблици с едно и също име, освен случая. Имената на колоните така или иначе ще бъдат в правилния регистър.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. можем ли да назовем ограничение по подразбиране в Oracle

  2. Как да отпечатам триъгълник от звезди с помощта на SQL

  3. Поетапно APPL_TOP в Oracle Applications R12

  4. Кой тип JDBC драйвер трябва да използвам за достъп до база данни на Oracle?

  5. БЛОКИРАНа нишка при изпълнение на процедура на Oracle от Java клас