0

私の希望する出力は次のとおりです。

<?xml version="1.0"?>
<Accounts>
    <Account>
        <variable1>variable1</variable1>
        <variable2>variable2</variable2>
        <variable3>variable3</variable3>
        <variable4>variable4</variable4>
        <variable5>variable5</variable5>
        <variable6>variable6</variable6>
        <Table>
            <Row>
                <Column1>row1col1</Column1>
                <Column2>row1col2</Column2>
                <Column3>row1col3</Column3>
            </Row>
            <Row>
                <Column1>row2col1</Column1>
                <Column2>row2col2</Column2>
                <Column3>row2col3</Column3>
            </Row>
            <Row>
                <Column1>row3col1</Column1>
                <Column2>row3col2</Column2>
                <Column3>row3col3</Column3>
            </Row>
        </Table>
    </Account>
    ...
</Accounts>

これから取得する必要のあるSQL関数は、現在アカウントをループし、アカウントIDごとに、変数1、2、テーブルなど、アカウントごとに上記のすべての関連データを収集します。したがって、アカウントIDごとに、すべての変数とテーブルを返します。 3列とすべての行。

したがって、単純化するために、すべてのアカウントIDについて、XMLファイルには上記の構造をファイルに追加する必要があります。これらのさまざまな部分をすべて含むXMLファイルを作成しようとすると、ジレンマが発生します。

最初の問題は、テーブル情報と変数情報を1つのXMLツリーに結合する方法です。テーブルから要素を使用してXMLフォレストを作成することは可能ですが、問題は、アカウントごとに一連の変数データとテーブルがあることです。table_to_xmlを検討しましたが、これはテーブルから直接取得し、table/xmlの前に変数要素を追加する方法がわかりません。

私はテキスト配列を行うことを検討しました:

for rec in execute cmd
loop

  cmd:= 'select xmlelement(name "Account",
        xmlelement(name "Variable1", '||var1||'))';

  execute cmd into vtext
  varray[n] := vtext;
  n++
end loop;

そして、おそらくテキスト配列としてxmlelementにネストされたテーブルを配置します。すべてが揃うまでネストを続け、すべてが揃ったらXMLに送信します。

次の問題は、これらすべてのアカウントを同じXM​​Lファイル内の1つの包括的な要素に結合することです。

誰かがこれを解決するためにアプローチする方法について何かアイデアを持っているなら、私は助けを大いに感謝します。プロセス全体を考えすぎているように感じます。あるいは、SQLで行うのはばかげすぎて、Pythonなどのスクリプト言語でこれらの操作を試す必要があるかもしれません。

4

1 に答える 1

0

問題の解決策は非常に簡単でした。すべてのデータを一時テーブルに配置し、連結します。具体的には、希望する出力に対してこれを行う方法:

-- FUNCTION AFTER CREATE AND DECLARES
v_cmd := 'select Accounts from <table>';

final_xml := '<?xml version="1.0"?><Accounts>';

for record in execute v_cmd
loop
    <generate Account data into SQL variables>

    -- Check if temp table exists, then create P1
    v_table_name1 := '<temp_table1>';

    IF EXISTS (select 1 from information_schema.tables 
    where table_schema = '<schema>' and table_name = <temp_table1>) THEN
        v_s_cmd := 'DROP TABLE '||<temp_table1>;
        execute v_s_cmd;
    END IF;

    v_s_cmd := 'CREATE TABLE <temp_table1>
    (variable1 varchar, variable2 varchar, ...)';
    execute v_s_cmd;
    v_s_cmd := 'INSERT INTO <temp_table1> 
    (variable1, variable2, ...)
    VALUES ('||coalesce(quote_literal(Account.variable1),'NULL')||',' 
           ''||coalesce(quote_literal(Account.variable2),'NULL')||',' ...)'';
    execute v_s_cmd;

    <generate multiple row data to be elements of the above Account>

    -- Check if temp table exists, then create P1
    v_table_name2 := '<temp_table2>';

    IF EXISTS (select 1 from information_schema.tables 
    where table_schema = '<schema>' and table_name = <temp_table2>) THEN
        v_s_cmd := 'DROP TABLE '||<temp_table2>;
        execute v_s_cmd;
    END IF;

    v_s_cmd := 'CREATE TABLE <temp_table2(Column1, Column2, Column3)';
    execute v_s_cmd;

    column_id = record.row_id;

    for column_record in

    SELECT Column1, Column2, Column3 FROM <column_data_source>
    WHERE data_id = column_id ORDER BY Column1, Column2, Column3

    loop
        v_s_cmd := 'INSERT INTO '||<temp_table2>|| 
        '(Column1, Column2, Column3, column_id) SELECT 
        '||quote_literal(column_record.Column1)||', 
        '||quote_literal(column_record.Column2)||', 
        '||quote_literal(column_record.Column2)||', 
        '''||column_id||''';';
        execute v_s_cmd;
    end loop;

    -- get var data 
    v_s_cmd := '(select regexp_replace((
    XMLElement(name Account, 
        XMLForest(variable1, variable2 ...)))::text,
        ''</Account>'','''',''g'') as var_d
    FROM <temp_table1>)';

    execute v_s_cmd into var_data;

    -- get Table data
    v_s_cmd := 'select XMLElement(name Row, 
                    XMLForest(Column1, Column2, Column3)) as test
                FROM '||<temp_table2>;

    table_rec := '<Table>';

    -- concatenate to variable
    for row_rec in execute v_s_cmd
    loop
        table_rec := table_rec || row_rec.test;
    end loop;
    table_rec := table_rec||'</Table></Account>';

    -- complete XML part and concatenate to main xml variable
    final_xml := final_xml || var_data || s_a_rec;

    v_s_cmd := 'drop table '||temp_table1;
    execute v_s_cmd;
    v_s_cmd := 'drop table '||temp_table2;
    execute v_s_cmd;

END LOOP;

final_xml := final_xml || '</Accounts>';

final_xml := XMLPARSE(DOCUMENT final_xml);

create table schema.temp_final_xml(xmlcode varchar);
insert into schema.temp_final_xml(xmlcode) VALUES (final_xml);

v_s_cmd := 'COPY (select xmlcode from schema.temp_final_xml) 
            TO ''/filepath/file.xml''';
execute v_s_cmd;

drop table schema.temp_final_xml;

この操作を実行するためのよりクリーンな方法があれば、私はそれを知りたいです。私はこれを思い付くために数日間頭を悩ませました。

于 2013-02-26T20:12:47.547 に答える