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 函数循环通过 Accounts 和每个帐户 ID 收集每个帐户上面的所有相关数据,例如变量 1、2、表等。因此,每个帐户 ID 它返回所有变量和表及其3 列和所有行。

因此,为了简化,对于每个 Account ID,XML 文件需要将上述结构附加到文件中。现在,当我尝试创建包含所有这些不同部分的 XML 文件时,我的困境就来了。

第一个问题是如何将表信息和变量信息组合成一个 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。

下一个问题是将所有这些帐户组合到同一个 XML 文件中的一个总体元素中。

如果有人对如何解决这个问题有任何想法,我将不胜感激。我觉得我在考虑整个过程,或者用 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 回答