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

pl/sqlのxmlelementを使用してすべてのリレーショナル表データを取得します

    データディクショナリクエリを組み合わせて親子関係とDBMS_XMLGEN.GETXMLを見つける関数を作成できます。 XMLを生成して結合します。

    以下の関数はROWIDを取ります 、親と子のテーブルを検索し、関連する行のXMLを生成します。ここには多くの仮定があり、実際のデータを処理するには膨大な作業が必要になる場合があります。

    create or replace function get_related_xml(p_rowid rowid) return xmltype is
        v_child_table_owner varchar2(128);
        v_child_table_name varchar2(128);
    
        v_parent_table_owner varchar2(128);
        v_parent_table_name varchar2(128);
        v_column varchar2(128);
    
        v_child_xml xmltype;
        v_parent_xml xmltype;
        v_combined_xml xmltype;
    begin
        --Get child table directly referenced by ROWID.
        select owner, object_name
        into v_child_table_owner, v_child_table_name
        from all_objects
        where object_type = 'TABLE'
            and object_id = dbms_rowid.rowid_object(p_rowid);
    
        --Get parent table based on child table ROWID, and join columns.
        --(ASSUMPTION: Tables only have one column, with the same name, that joins the tables.)
        select owner, table_name, column_name
        into v_parent_table_owner, v_parent_table_name, v_column
        from all_cons_columns
            where (owner, constraint_name) in
            (
                --Foreign key constraints based on the relevant table.
                select r_owner, r_constraint_name
                from all_constraints
                where constraint_type = 'R'
                    and (owner, table_name) in
                    (
                        --Table referenced by ROWID.
                        select owner, object_name
                        from all_objects
                        where object_type = 'TABLE'
                            and object_id = dbms_rowid.rowid_object(p_rowid)
                    )
            );
    
        --Generate child XML.
        v_child_xml := dbms_xmlgen.getXMLType
            (
                'select c.*
                from '||v_child_table_owner||'.'||v_child_table_name||' c
                join '||v_parent_table_owner||'.'||v_parent_table_name||' p
                    on c.'||v_column||' = p.'||v_column||'
                where c.rowid = '''||p_rowid||''''
            );
    
        --Generate parent XML.
        v_parent_xml := dbms_xmlgen.getXMLType
            (
                'select p.*
                from '||v_child_table_owner||'.'||v_child_table_name||' c
                join '||v_parent_table_owner||'.'||v_parent_table_name||' p
                    on c.'||v_column||' = p.'||v_column||'
                where c.rowid = '''||p_rowid||''''
            );
    
        --Combine the XML and return them.
        select xmlconcat(v_child_xml, v_parent_xml)
        into v_combined_xml
        from dual;
    
        return v_combined_xml;
    end get_related_xml;
    /
    

    関数の呼び出しは簡単です。現在のバージョンでは、希望する形式のデータが正確に返されません。XMLを変換する必要がある場合があります。

    select get_related_xml(rowid)
    from table1
    where rollno=15;
    
    <ROWSET>
     <ROW>
      <ID>2</ID>
      <NAME>bbb</NAME>
      <ROLLNO>15</ROLLNO>
     </ROW>
    </ROWSET>
    <ROWSET>
     <ROW>
      <ID>2</ID>
      <ROLLNO>15</ROLLNO>
      <DIV>b</DIV>
     </ROW>
    </ROWSET>
    

    上記の結果を生成するために使用したサンプルスキーマは次のとおりです。これは、両方のテーブルで同じ名前を持つ単一の列に基づく、親子関係が1つだけの単純なスキーマです。

    create table table2(id number primary key, rollNo number unique, div varchar2(100));
    insert into table2
    select 1, 10, 'a' from dual union all
    select 2, 15, 'b' from dual;
    
    create table table1(id number primary key, name varchar2(100), rollNo number,
        constraint table1_fk foreign key (rollNo) references table2(rollNo));
    insert into table1
    select 1, 'aaa', 10 from dual union all
    select 2, 'bbb', 15 from dual;
    



    1. postgresでランタイムメッセージを印刷する

    2. MySQLの同じテーブルを参照するサブクエリを使用したSQLUPDATE

    3. PLSQLブロックに複数のDMLクエリがある場合、影響を受ける行の集計を計算するにはどうすればよいですか?

    4. MySQLはEC2で非常に遅い