XQuery选择并检查现有员工的消息

时间:2017-05-27 00:33:20

标签: oracle oracle-sqldeveloper xquery xquery-sql

我需要使用xquery在列中输出“匹配”或“不是雇员”的消息。我现在使用4444作为占位符,不知道如何在查询中迭代

SELECT
EXTRACTVALUE(B.JOBSHEET_DETAILS, '/jobSheet[@jobNo]/@jobNo') AS "JOB_DETAILS_ID",
XMLQUERY(' for $j in /jobSheet/employee[@empNo]/@empNo
        let $msg := if ($j) then "Employee details match a current employee" else "Error in employee details (no match)"
        where $j = 4444
        return $msg
        '
        PASSING B.JOBSHEET_DETAILS
        RETURNING CONTENT ).getstringval() AS "CHECK_EMP_DETAILS" ,
EXTRACTVALUE(B.JOBSHEET_DETAILS, '/jobSheet/employee[@empNo]/@empNo') AS "EMP_NO",
EXTRACTVALUE(B.JOBSHEET_DETAILS, '/jobSheet/employee/empName') AS "EMP_NAME",
EXTRACTVALUE(B.JOBSHEET_DETAILS, '/jobSheet/dateAttend/date') AS "DATE_ATTENDED"
FROM JOBSHEET_XML_TAB B
where XMLEXISTS('/jobSheet/employee[@empNo]/@empNo' passing B.JOBSHEET_DETAILS);

对于一个,xmlquery中的 else 不会触发。当它应该是一个错误时输出(null)。

enter image description here

如果此次迭代中的$ j是现有员工,我需要检查所有员工。 $ j = 4444是否可以从emp执行另一个选择计数(*),其中no = $ num。

1 个答案:

答案 0 :(得分:0)

如果可能的话,我根本不会尝试在XPath中这样做。您可以使用XMLQuery() or XMLTable()提取您感兴趣的元素和属性值,然后外连接到emp表以检查它们是否存在,并使用case表达式来决定要显示的文本

根据您当前代码的XML结构,例如:

select x.job_details_id,
  case when e.no is not null then 'Employee details match a current employee'
    else 'Error in employee details (no match)' end as check_emp_details,
  x.emp_no,
  x.emp_name,
  x.date_attended
from jobsheet_xml_tab jxt
cross join XMLTable(
  '/jobSheet/employee[@empNo]'
  passing jxt.jobsheet_details
  columns job_details_id number path './../@jobNo',
    emp_no number path './@empNo',
    emp_name varchar2(20) path './empName',
    date_attended date path './../dateAttend/date'
) x
left join emp e on e.no = x.emp_no;

在CTE中使用简化的XML和emp记录进行快速演示:

with jobsheet_xml_tab(jobsheet_details) as (
  select xmltype('<jobSheet jobNo="666666">
 <dateAttend>
  <date>2017-05-01</date>
 </dateAttend>
 <employee empNo="7777">
  <empName>Joe</empName>
 </employee>
</jobSheet>') from dual
  union all
  select xmltype('<jobSheet jobNo="777777">
 <dateAttend>
  <date>2017-05-03</date>
 </dateAttend>
 <employee empNo="4444">
  <empName>Jane</empName>
 </employee>
</jobSheet>') from dual
),
emp (no) as (
  select 4444 from dual
)
select x.job_details_id,
  case when e.no is not null then 'Employee details match a current employee'
    else 'Error in employee details (no match)' end as check_emp_details,
  x.emp_no,
  x.emp_name,
  x.date_attended
from jobsheet_xml_tab jxt
cross join XMLTable(
  '/jobSheet/employee[@empNo]'
  passing jxt.jobsheet_details
  columns job_details_id number path './../@jobNo',
    emp_no number path './@empNo',
    emp_name varchar2(20) path './empName',
    date_attended date path './../dateAttend/date'
) x
left join emp e on e.no = x.emp_no;

JOB_DETAILS_ID CHECK_EMP_DETAILS                             EMP_NO EMP_NAME             DATE_ATTE
-------------- ----------------------------------------- ---------- -------------------- ---------
        666666 Error in employee details (no match)            7777 Joe                  01-MAY-17
        777777 Employee details match a current employee       4444 Jane                 03-MAY-17

它可能没用,但原则上这可以应付分配给它的多个员工的工作,而使用已弃用的extractvalue()却不能。