Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 带3个表的PostgreSQL到XML_Php_Sql_Xml_Database_Postgresql - Fatal编程技术网

Php 带3个表的PostgreSQL到XML

Php 带3个表的PostgreSQL到XML,php,sql,xml,database,postgresql,Php,Sql,Xml,Database,Postgresql,我是一个小型开发团队的实习生,我的项目负责人希望我编写一个将PostgreSQL数据导出到XML文件的函数。不幸的是,我只知道如何将导出写入csv 有3个不同的表,他希望这样(XML视图) .... ... 这些标记分别表示我的表名。如何编写导出此文件的代码 关于StackOverflow的其他问题主要集中在导出单个表上,因此我希望这个问题也能帮助尝试导出多个表的其他人 您有三层嵌套表 样本数据: 方法1:执行左连接,在客户机中处理XML 处理此问题的最简单方法是对所有三个表进行左联接,从最

我是一个小型开发团队的实习生,我的项目负责人希望我编写一个将PostgreSQL数据导出到XML文件的函数。不幸的是,我只知道如何将导出写入csv

有3个不同的表,他希望这样(XML视图)


....
...
这些标记分别表示我的表名。如何编写导出此文件的代码


关于StackOverflow的其他问题主要集中在导出单个表上,因此我希望这个问题也能帮助尝试导出多个表的其他人

您有三层嵌套表

样本数据: 方法1:执行左连接,在客户机中处理XML 处理此问题的最简单方法是对所有三个表进行左联接,从最外层到最内层排序。然后遍历结果集,在该级别的主题发生变化时关闭一个元素并打开另一个元素

select *
from a left join b on (a.a_id = b.a_id)
       left join c on (b.b_id = c.b_id)
order by a.a_id, b.b_id, c.c_id;
然后循环返回的行,对于每一行,伪代码

cur_row = get_new_row()

if (cur_row[b_id] != prev_row[b_id]) {
   emit_close_tableb();
}
if (cur_row[a_id] != prev_row[a_id]) {
   emit_close_tablea();
   emit_open_tablea(cur_row);
}
if (cur_row[b_id] != prev_row[b_id]) {
   emit_open_tableb(cur_row);
}
emit_tablec(cur_row);

prev_row = cur_row;
要编写XML,您可以使用以下内容。要读取查询数据,可以使用PDO或任何您喜欢的驱动程序。如果数据集较大,请考虑使用光标读取数据。< /P> 这工作得很好,但它传输了大量多余的数据,因为您要为与之关联的内部表的每个
n
行传输外部表数据的副本


为了减少交换的多余数据,您只能选择外部表的ID

select a.a_id, b.b_id, c.*
from a left join b on (a.a_id = b.a_id)
       left join c on (b.b_id = c.b_id)
order by a.a_id, b.b_id, c.c_id;
。。。然后,当您切换到一个新表a/tableb时,
选择它的其余行。您可能会使用第二个连接来执行此操作,这样就不会中断正在从中读取行的主连接上的结果集和光标状态

方法2:在PostgreSQL中完成所有操作 对于较小的数据集或较大数据集的内部级别,您可以使用PostgreSQL的XML支持来构建XML文档,例如:

WITH xmlinput AS (
  SELECT a, b, c
  FROM a
  LEFT JOIN b ON (a.a_id = b.a_id)
  LEFT JOIN c on (b.b_id = c.b_id)
  ORDER BY a.a_id, b.b_id, c.c_id
)
SELECT
  XMLELEMENT(name items,
    xmlagg(
      XMLELEMENT(name a,
        XMLFOREST((a).a_id AS a_id, (a)."name" AS name),
        b_xml
      )
    ORDER BY (a).a_id)
  ) AS output
FROM
(
  SELECT
    a,
    xmlagg(
      XMLELEMENT(name b,
        XMLFOREST((b).b_id AS b_id, (b).val AS val),
        c_xml
      )
    ORDER BY (b).b_id)
    AS b_xml
  FROM
  (
    SELECT
      a, b,
      xmlagg(
        XMLELEMENT(name c,
          XMLFOREST((c).c_id AS c_id, (c).blah AS blah)
        )
      ORDER BY (c).c_id)
      AS c_xml
    FROM xmlinput
    GROUP BY a, b
  ) c_as_xml
  GROUP BY a
) b_as_xml;
。。。但实际上,你必须是一个受虐狂才能写出这样的代码。虽然它可能被证明是相当快的

理解查询。奇怪的语法是SQL/XML委员会想出的,不要怪我们

还要注意的是,在上面的代码中大量使用了行变量,以保持其组织性
a
b
c
作为整行传递给查询的外层。这样可以避免在名称冲突时混淆别名。语法
(a).a_id
等表示“行变量
a
a_id
字段”。有关详细信息,请参阅PostgreSQL手册

上面使用了更好的XML结构(参见下面的注释)。如果要发出属性而不是元素,可以将
xmlfreest
调用更改为
xmldattributes
调用

输出:

<items><a><a_id>1</a_id><name>fred</name><b><b_id>11</b_id><val>x</val><c><c_id>1</c_id><blah>whatever</blah></c><c><c_id>2</c_id><blah>gah</blah></c></b><b><b_id>12</b_id><val>y</val><c><c_id>3</c_id><blah>borkbork</blah></c></b></a><a><a_id>2</a_id><name>bert</name><b><b_id>21</b_id><val>a</val><c/></b><b><b_id>22</b_id><val>b</val><c><c_id>4</c_id><blah>fuzz</blah></c></b></a></items>
1fred11x12gah12y3borkbork2bert2a22b4fuzz是什么
或者,漂亮的印刷品:

<?xml version="1.0" encoding="utf-16"?>
<items>
    <a>
        <a_id>1</a_id>
        <name>fred</name>
        <b>
            <b_id>11</b_id>
            <val>x</val>
            <c>
                <c_id>1</c_id>
                <blah>whatever</blah>
            </c>
            <c>
                <c_id>2</c_id>
                <blah>gah</blah>
            </c>
        </b>
        <b>
            <b_id>12</b_id>
            <val>y</val>
            <c>
                <c_id>3</c_id>
                <blah>borkbork</blah>
            </c>
        </b>
    </a>
    <a>
        <a_id>2</a_id>
        <name>bert</name>
        <b>
            <b_id>21</b_id>
            <val>a</val>
            <c />
        </b>
        <b>
            <b_id>22</b_id>
            <val>b</val>
            <c>
                <c_id>4</c_id>
                <blah>fuzz</blah>
            </c>
        </b>
    </a>
</items>

1.
弗雷德
11
x
1.
无论什么
2.
嘎
12
Y
3.
博克博克
2.
伯特
21
A.
22
B
4.
绒毛
请发出更好的XML 另一方面,在XML中使用这样的属性似乎很诱人,但很快就会变得困难和难看。请仅使用普通XML元素:

  <Table 1>
    <Nr>1</Nr>
    <Name>blah</Name>
     <Table 2>
       <Nr>1</Nr>
       <Table 3>
          <Col1>42</Col1>
          <Col2>...</Col2>
          <Col3>...</Col3>
          <Col4>...</Col4>
          ...
       </Table 3>
     </Table 2>
   </Table 1>

1.
废话
1.
42
...
...
...
...

我想你会熟悉PHP的。谢谢,但这有点让人困惑。我会试试这个,但是如果你有点空闲的话,你能试着给我看一个不使用我的变量的示例吗?@sguetsch在上面,我
tablea
=
Konzern
tableb
=
HSN
tablec
=
TSN
,如果我正确理解了你的例子。要点是使用一系列从最外层到最内层的结果的左连接,并在结果集上迭代,当行之间发生变化时打开和关闭标记。@sguetsch顺便说一句,如果数据相当小,您可以完全在PostgreSQL中完成,只需使用SQL。如果我想给你看一些有用的例子,你必须实际提供一些可用的数据作为一个或类似的例子。是的,你理解得对:)谢谢你的帮助up@sguetsch我还添加了一个仅使用PostgreSQL查询生成XML的示例。不过,如果采用这种方法,您会希望对SQL非常熟悉。
<?xml version="1.0" encoding="utf-16"?>
<items>
    <a>
        <a_id>1</a_id>
        <name>fred</name>
        <b>
            <b_id>11</b_id>
            <val>x</val>
            <c>
                <c_id>1</c_id>
                <blah>whatever</blah>
            </c>
            <c>
                <c_id>2</c_id>
                <blah>gah</blah>
            </c>
        </b>
        <b>
            <b_id>12</b_id>
            <val>y</val>
            <c>
                <c_id>3</c_id>
                <blah>borkbork</blah>
            </c>
        </b>
    </a>
    <a>
        <a_id>2</a_id>
        <name>bert</name>
        <b>
            <b_id>21</b_id>
            <val>a</val>
            <c />
        </b>
        <b>
            <b_id>22</b_id>
            <val>b</val>
            <c>
                <c_id>4</c_id>
                <blah>fuzz</blah>
            </c>
        </b>
    </a>
</items>
  <Table 1>
    <Nr>1</Nr>
    <Name>blah</Name>
     <Table 2>
       <Nr>1</Nr>
       <Table 3>
          <Col1>42</Col1>
          <Col2>...</Col2>
          <Col3>...</Col3>
          <Col4>...</Col4>
          ...
       </Table 3>
     </Table 2>
   </Table 1>