我需要执行在SQL中相当常见的分层查询。 但现在我需要使用Xquery在xml文档上做同样的事情。
举个例子,我正在为其递归的CONNECT BY功能建模一个标准的Oracle教程。 这是表,但转换为xml:
<EMPLOYEES>
<EMP>
<EMPNO>7369</EMPNO>
<ENAME>SMITH</ENAME>
<JOB>CLERK</JOB>
<MGR>7902</MGR>
<HIREDATE>17-DEC-80</HIREDATE>
<SAL>800</SAL>
</EMP>
<EMP>
<EMPNO>7499</EMPNO>
<ENAME>ALLEN</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>20-FEB-81</HIREDATE>
<SAL>1600</SAL>
<COMM>300</COMM>
</EMP>
<EMP>
<EMPNO>7521</EMPNO>
<ENAME>WARD</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>22-FEB-81</HIREDATE>
<SAL>1250</SAL>
<COMM>500</COMM>
</EMP>
<EMP>
<EMPNO>7566</EMPNO>
<ENAME>JONES</ENAME>
<JOB>MANAGER</JOB>
<MGR>7839</MGR>
<HIREDATE>02-APR-81</HIREDATE>
<SAL>2975</SAL>
</EMP>
<EMP>
<EMPNO>7654</EMPNO>
<ENAME>MARTIN</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>28-SEP-81</HIREDATE>
<SAL>1250</SAL>
<COMM>1400</COMM>
</EMP>
<EMP>
<EMPNO>7698</EMPNO>
<ENAME>BLAKE</ENAME>
<JOB>MANAGER</JOB>
<MGR>7839</MGR>
<HIREDATE>01-MAY-81</HIREDATE>
<SAL>2850</SAL>
</EMP>
<EMP>
<EMPNO>7782</EMPNO>
<ENAME>CLARK</ENAME>
<JOB>MANAGER</JOB>
<MGR>7839</MGR>
<HIREDATE>09-JUN-81</HIREDATE>
<SAL>2450</SAL>
</EMP>
<EMP>
<EMPNO>7788</EMPNO>
<ENAME>SCOTT</ENAME>
<JOB>ANALYST</JOB>
<MGR>7566</MGR>
<HIREDATE>19-APR-87</HIREDATE>
<SAL>3000</SAL>
</EMP>
<EMP>
<EMPNO>7839</EMPNO>
<ENAME>KING</ENAME>
<JOB>PRESIDENT</JOB>
<HIREDATE>17-NOV-81</HIREDATE>
<SAL>5000</SAL>
</EMP>
<EMP>
<EMPNO>7844</EMPNO>
<ENAME>TURNER</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>08-SEP-81</HIREDATE>
<SAL>1500</SAL>
<COMM>0</COMM>
</EMP>
<EMP>
<EMPNO>7876</EMPNO>
<ENAME>ADAMS</ENAME>
<JOB>CLERK</JOB>
<MGR>7788</MGR>
<HIREDATE>23-MAY-87</HIREDATE>
<SAL>1100</SAL>
</EMP>
<EMP>
<EMPNO>7900</EMPNO>
<ENAME>JAMES</ENAME>
<JOB>CLERK</JOB>
<MGR>7698</MGR>
<HIREDATE>03-DEC-81</HIREDATE>
<SAL>950</SAL>
</EMP>
<EMP>
<EMPNO>7902</EMPNO>
<ENAME>FORD</ENAME>
<JOB>ANALYST</JOB>
<MGR>7566</MGR>
<HIREDATE>03-DEC-81</HIREDATE>
<SAL>3000</SAL>
</EMP>
<EMP>
<EMPNO>7934</EMPNO>
<ENAME>MILLER</ENAME>
<JOB>CLERK</JOB>
<MGR>7782</MGR>
<HIREDATE>23-JAN-82</HIREDATE>
<SAL>1300</SAL>
</EMP>
</EMPLOYEES>
我正在尝试模拟SYS_CONNECT_BY_PATH函数,并为给定的员工生成组织层次结构。例如,员工ADAMS ......
KING JONES SCOTT ADAMS
链接在emp id和他的mgr代码之间。
看起来像递归字符串连接函数可以解决问题,但我对Xquery来说太新了,无法使语法工作。
我的部分融合源于'Hierachy'的概念。这不是我需要追逐的文件层次。层次结构在数据中;渲染更像是一个链表。
任何想法都会受到赞赏。
答案 0 :(得分:0)
理想情况下,XML将按层次结构格式化,因此组织隐含在XML中,您需要做的就是获取员工祖先(或后代)。在这种情况下,您可以编写一个递归函数,该函数遵循从员工到经理员工的基于ID的链接的路径:
declare function local:boss-R(
$emp as element(EMP)?
) as xs:string*
{
if (empty($emp)) then ()
else
let $boss := $emp/ancestor::EMPLOYEES/EMP[EMPNO eq $emp/MGR]
return ($boss/ENAME/string(), local:boss-R($boss))
};
declare function local:org(
$emp as element(EMP)
) as xs:string+
{
$emp/ENAME, local:boss-R($emp)
};
let $emp := doc('employees.xml')/EMPLOYEES/EMP[1]
return reverse(local:org($emp))