我需要使用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)。
如果此次迭代中的$ j是现有员工,我需要检查所有员工。 $ j = 4444是否可以从emp执行另一个选择计数(*),其中no = $ num。
答案 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()
却不能。