在 XML 中显示层次结构
Display the hierarchy in XML
我有以下 table:
员工 (id int,name varchar,managerid int)
ID NAME MANAGERID
1 A 2
2 B 4
3 C 4
4 D NULL
期望输出:
<Node name="D" id="4">
<Node name="B" id="2">
<Node name="A" id="1">
</Node>
</Node>
<Node name="C" id="3">
</Node>
</Node>
现在,我知道这不过是深度优先搜索,所以我完成了以下操作:
WITH t1(id,name,managerid) AS (
-- Anchor member.
SELECT id,
name,
managerid
FROM employee
WHERE managerid IS NULL
UNION ALL
-- Recursive member.
SELECT t2.id,
t2.name,
t2.managerid
FROM employee t2, t1
WHERE t2.managerid = t1.id
)
SEARCH DEPTH FIRST BY id SET order1
SELECT id,
name,
managerid
FROM t1
ORDER BY order1\
而上述查询的输出是:
ID NAME MANAGERID
4 D NULL
2 B 4
1 A 2
3 C 4
现在,我不知道如何将此输出转换为之前显示的 xml 版本。
我知道有 XMLElement
、XMLAGG
等函数,但我不知道如何在这种分层查询中使用它。
注意:目前,我在 Oracle 中执行此操作,但如果另一个 RDBMS 有更简单的方法来解决此问题,那么我完全赞成。
您可以使用 dbms_xmlgen.newcontextFromHierarchy 执行此操作,如下所示:
select dbms_xmlgen.getxmltype(dbms_xmlgen.newcontextFromHierarchy('
WITH sample_data AS (SELECT 1 ID, ''A'' NAME, 2 managerid FROM dual UNION ALL
SELECT 2 ID, ''B'' NAME, 4 managerid FROM dual UNION ALL
SELECT 3 ID, ''C'' NAME, 4 managerid FROM dual UNION ALL
SELECT 4 ID, ''D'' NAME, NULL FROM dual)
select level
, xmlelement("node"
, XMLAttributes(name as "name",
id as "id")
)
FROM sample_data
CONNECT BY PRIOR ID = managerid
START WITH managerid IS NULL
')) from dual;
哪个returns:
<?xml version="1.0"?>
<node name="D" id="4">
<node name="B" id="2">
<node name="A" id="1"/>
</node>
<node name="C" id="3"/>
</node>
您需要将 dbms_xmlgen.newcontextFromHierarchy()
调用中的查询替换为您的实际查询。
如果您模拟 connect by
的 level
列,则可以使用 DBMS_XMLGEN.newcontextfromhierarchy 和 CTE 完成此操作:
SELECT DBMS_XMLGEN.getXML(DBMS_XMLGEN.newcontextfromhierarchy('
with employee as (
select 1 id, ''A'' name, 2 managerid from dual union all
select 2 id, ''B'' name, 4 managerid from dual union all
select 3 id, ''C'' name, 4 managerid from dual union all
select 4 id, ''D'' name, null managerid from dual
)
, t1(lvl,id,name,managerid) AS (
-- Anchor member.
SELECT 1 as lvl,
id,
name,
managerid
FROM employee
WHERE managerid IS NULL
UNION ALL
-- Recursive member.
SELECT t1.lvl+1 as lvl,
t2.id,
t2.name,
t2.managerid
FROM employee t2, t1
WHERE t2.managerid = t1.id
)
SEARCH DEPTH FIRST BY id SET order1
SELECT lvl, xmlelement("Node", xmlattributes(name AS "name", id AS "id"))
FROM t1
ORDER BY order1
'))
FROM dual
输出
<?xml version="1.0"?>
<Node name="D" id="4">
<Node name="B" id="2">
<Node name="A" id="1"/>
</Node>
<Node name="C" id="3"/>
</Node>
我有以下 table:
员工 (id int,name varchar,managerid int)
ID NAME MANAGERID
1 A 2
2 B 4
3 C 4
4 D NULL
期望输出:
<Node name="D" id="4">
<Node name="B" id="2">
<Node name="A" id="1">
</Node>
</Node>
<Node name="C" id="3">
</Node>
</Node>
现在,我知道这不过是深度优先搜索,所以我完成了以下操作:
WITH t1(id,name,managerid) AS (
-- Anchor member.
SELECT id,
name,
managerid
FROM employee
WHERE managerid IS NULL
UNION ALL
-- Recursive member.
SELECT t2.id,
t2.name,
t2.managerid
FROM employee t2, t1
WHERE t2.managerid = t1.id
)
SEARCH DEPTH FIRST BY id SET order1
SELECT id,
name,
managerid
FROM t1
ORDER BY order1\
而上述查询的输出是:
ID NAME MANAGERID
4 D NULL
2 B 4
1 A 2
3 C 4
现在,我不知道如何将此输出转换为之前显示的 xml 版本。
我知道有 XMLElement
、XMLAGG
等函数,但我不知道如何在这种分层查询中使用它。
注意:目前,我在 Oracle 中执行此操作,但如果另一个 RDBMS 有更简单的方法来解决此问题,那么我完全赞成。
您可以使用 dbms_xmlgen.newcontextFromHierarchy 执行此操作,如下所示:
select dbms_xmlgen.getxmltype(dbms_xmlgen.newcontextFromHierarchy('
WITH sample_data AS (SELECT 1 ID, ''A'' NAME, 2 managerid FROM dual UNION ALL
SELECT 2 ID, ''B'' NAME, 4 managerid FROM dual UNION ALL
SELECT 3 ID, ''C'' NAME, 4 managerid FROM dual UNION ALL
SELECT 4 ID, ''D'' NAME, NULL FROM dual)
select level
, xmlelement("node"
, XMLAttributes(name as "name",
id as "id")
)
FROM sample_data
CONNECT BY PRIOR ID = managerid
START WITH managerid IS NULL
')) from dual;
哪个returns:
<?xml version="1.0"?>
<node name="D" id="4">
<node name="B" id="2">
<node name="A" id="1"/>
</node>
<node name="C" id="3"/>
</node>
您需要将 dbms_xmlgen.newcontextFromHierarchy()
调用中的查询替换为您的实际查询。
如果您模拟 connect by
的 level
列,则可以使用 DBMS_XMLGEN.newcontextfromhierarchy 和 CTE 完成此操作:
SELECT DBMS_XMLGEN.getXML(DBMS_XMLGEN.newcontextfromhierarchy('
with employee as (
select 1 id, ''A'' name, 2 managerid from dual union all
select 2 id, ''B'' name, 4 managerid from dual union all
select 3 id, ''C'' name, 4 managerid from dual union all
select 4 id, ''D'' name, null managerid from dual
)
, t1(lvl,id,name,managerid) AS (
-- Anchor member.
SELECT 1 as lvl,
id,
name,
managerid
FROM employee
WHERE managerid IS NULL
UNION ALL
-- Recursive member.
SELECT t1.lvl+1 as lvl,
t2.id,
t2.name,
t2.managerid
FROM employee t2, t1
WHERE t2.managerid = t1.id
)
SEARCH DEPTH FIRST BY id SET order1
SELECT lvl, xmlelement("Node", xmlattributes(name AS "name", id AS "id"))
FROM t1
ORDER BY order1
'))
FROM dual
输出
<?xml version="1.0"?>
<Node name="D" id="4">
<Node name="B" id="2">
<Node name="A" id="1"/>
</Node>
<Node name="C" id="3"/>
</Node>