sql >> Databáze >  >> RDS >> Oracle

generovat XML z tabulek Oracle

Oracle má vestavěnou funkci pro získání obsahu tabulky jako 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>

Kolem toho můžete přidat své vlastní značky; lze provést jako dotaz, ale protože chcete uloženou proceduru:

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>

Takže to má strukturu, kterou chcete (no, myslím, ale viz níže), ale má ROWSET a ROW místo RECORDS a RECORD . To může nezáleží, záleží na tom, zda stále vyvíjíte formát pro toto rozhraní. Pokud na tom záleží, můžete použít další krok pro přejmenování těchto uzlů , nebo - což je užitečnější - použijte dbms_xmlgen procedury setrowsettag a setrowtag , což je ve vašem postupu jednoduché (a ukázáno níže).

Předpokládám, že to, co jste ukázali jako <TABLENAME></TABLENAME> byla chyba a chcete záznamy v této značce. Pokud ne a z nějakého důvodu to opravdu chcete, změňte dotaz ve funkci na:

  select xmlelement("XML",
      xmlconcat(xmlelement(evalname(table_name), null),
      dbms_xmlgen.getxmltype('select * from "' || table_name || '"')))
  into xml
  from dual;

To pak můžete zapsat do souboru jakýmkoli způsobem, který byste normálně dělali; pokud voláte z SQL*Plus atd., můžete vybrat a zařadit, nebo pokud nechcete, aby se to vrátilo vůbec, můžete přidat UTL_FILE direktiva pro zápis souboru z procedury, ale to by muselo být do objektu adresáře na serveru DB, což nemusí být vhodné.

Většinou pro můj vlastní prospěch, protože s XML toho moc nedělám:

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;
/

Při spuštění pomocí exec table_to_xml_file('T42') , vytvoří se soubor s názvem T42.xml v adresáři serveru, na který ukazuje <directory> adresářový objekt, který obsahuje:

<XML>
  <T42>
    <RECORDS>
      <RECORD>
        <ID>1</ID>
        <STR>AA</STR>
      </RECORD>
      <RECORD>
        <ID>2</ID>
        <STR>BB</STR>
      </RECORD>
    </RECORDS>
  </T42>
</XML>

Mimochodem, dal jsem název tabulky do uvozovek ve výběru uvnitř dbms_xmlgen.getxmltype volání. To je pro splnění požadavku 'případ by měl být stejný jako v databázi' pro název tabulky; musí být předán postupu ve správném případě, jinak dojde k chybě. Je to jednodušší, než se nějak pokoušet opravit případ v rámci procedury, což by bylo nešikovné nebo nemožné, pokud byste kromě případu měli dvě tabulky se stejným názvem. Názvy sloupců budou stejně ve správných velikostech.




  1. Získejte ovlivněné řádky na ExecuteNonQuery

  2. Django, mod_wsgi, psycopg2 Nesprávně nakonfigurováno:Chyba při načítání modulu psycopg2:Žádný modul s názvem _psycopg

  3. ADO .NET vs. SQL Server Management Studio – ADO funguje hůře

  4. Sql Server Service Broker