【问题标题】:Query against recursive data using Xquery?使用 Xquery 查询递归数据?
【发布时间】:2013-11-08 16:19:46
【问题描述】:

我需要执行在 SQL 中相当常见的分层查询。 但现在我需要使用 Xquery 对 xml 文档做同样的事情。

例如,我正在根据标准 Oracle 教程对其递归 CONNECT BY 功能进行建模。 这是表格,但转换为 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 函数,并为给定员工生成 Org 层次结构。例如对于员工 ADAMS...

金琼斯·斯科特·亚当斯

链接在emp id和他的经理代码之间。

看起来递归字符串连接函数可以解决问题,但我对 Xquery 太陌生,无法使用语法。

我的部分观点源于“层次”的概念。这不是我需要追逐的文档层次结构。层次结构在数据中;渲染得更像一个链表。

任何想法都将不胜感激。

【问题讨论】:

    标签: recursion xquery


    【解决方案1】:

    理想情况下,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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-21
      • 1970-01-01
      • 2018-02-07
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      相关资源
      最近更新 更多