sql >> データベース >  >> RDS >> Oracle

Oracle テーブルから XML を生成する

    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 内の select で、テーブル名を二重引用符で囲みました。 電話。これは、テーブル名の「大文字と小文字はデータベースと同じでなければならない」という要件を満たすためです。正しいケースでプロシージャに渡す必要があります。そうしないと、エラーが発生します。これは、プロシージャ内で何らかの方法で大文字と小文字を修正しようとするよりも簡単です。これは、大文字と小文字が区別されている同じ名前のテーブルが 2 つある場合に厄介であるか、または不可能です。いずれにせよ、列名は大文字と小文字が正しくなります。




    1. Postgresでpgagentを介して作成されたジョブを実行する方法

    2. SELECTで挿入

    3. JSONデータを静的getJSON/Javascriptに渡すDjango

    4. JSONを編集して、「辞書」ではなく配列を作成するのに役立ちます