在我的 XMLQuery 中需要帮助。
获取循环序列
SELECT extractvalue(update_xmldoc, 'count(/invoice/AR_ITEMS/ITEMS[NAME="Voice" and ITEM_TOTAL!=0])')
INTO item_check
FROM xml_billrun_files
WHERE seq_id = seq
AND docname = REPLACE(fn,'.','_HULK.')
ORDER BY TIMESTAMP DESC;
然后 item_check 值将传递到循环
FOR lp IN 1..item_check LOOP
SELECT tst, bill_info_id, bill_no, dur_net_amt, dur_vat_amt, dur_pro_net_amt, dur_pro_vat_amt, sys_descr
INTO xmlU, bp, bill, net_amt1, vat_amt1, net_amt2, vat_amt2, disc_name
FROM
(SELECT row_number() over (partition BY t.docname order by t.timestamp DESC) rn,
t.docname,
XMLQuery('for $i in distinct-values(/invoice/AR_ITEMS['||lp||']/ITEMS/EVENTS/BAL_IMPACTS/DISCOUNT_INFO)
where $i = "Plan499 Corp Disc"
or $i = "Plan899 Corp Disc"
or $i = "Plan1099 Corp Disc"
or $i = "Plan1599 Corp Disc"
return $i' passing original_xmldoc returning content ).getStringVal() sys_descr
我只是发布了我的脚本的一部分。
脚本很好,但是当我在 XMLQuery 中传递 lp 的值时,出现错误
Error(528,66): PL/SQL: ORA-19109: RETURNING keyword expected
好的,下面是我的脚本的示例。
DECLARE
item_check NUMBER;
fn VARCHAR2(100) := 'test.xml';
seq NUMBER := 1;
BEGIN
SELECT extractvalue(update_xmldoc, 'count(/invoice/AR_ITEMS/ITEMS[NAME="Voice" and ITEM_TOTAL!=0])')
INTO item_check
FROM xml_billrun_files
WHERE seq_id = seq
AND docname = REPLACE(fn,'.','_HULK.')
ORDER BY TIMESTAMP DESC;
IF item_check <> 0 THEN
FOR lp IN 1..item_check LOOP
SELECT tst
INTO xmlU
FROM
(SELECT row_number() over (partition BY t.docname order by t.timestamp DESC) rn,
t.docname,
XMLQuery('for $i in distinct-values(/invoice/AR_ITEMS['||lp||']/ITEMS/EVENTS/BAL_IMPACTS/DISCOUNT_INFO)
where $i = "Plan499 Corp Disc"
or $i = "Plan899 Corp Disc"
or $i = "Plan1099 Corp Disc"
or $i = "Plan1599 Corp Disc"
return $i' passing original_xmldoc returning content ).getStringVal() sys_descr,
SUM(SUBSTR(x.chrg_duration,1,instr(x.chrg_duration,':',1)-1)) over (partition BY t.docname) chrg_duration,
CASE
WHEN extractvalue(xmltype('<DISCOUNT_INFO>'||XMLQuery('for $i in distinct-values(/invoice/AR_ITEMS/ITEMS/EVENTS/BAL_IMPACTS/DISCOUNT_INFO)
where $i = "Plan499 Corp Disc"
or $i = "Plan899 Corp Disc"
or $i = "Plan1099 Corp Disc"
or $i = "Plan1599 Corp Disc"
return $i' passing original_xmldoc returning content )||'</DISCOUNT_INFO>'),'DISCOUNT_INFO') = 'Plan499 Corp Disc' AND SUM(SUBSTR(x.chrg_duration,1,instr(x.chrg_duration,':',1)-1)) over (partition BY t.docname) <= prorate_mins
THEN insertchildxml(
insertchildxml(
updatexml(
updatexml(
updatexml(t.update_xmldoc,'/invoice/BILLINFO/TOTAL_DUE/text()',
extractvalue(t.update_xmldoc,'/invoice/BILLINFO/TOTAL_DUE') - SUM(x.amount) over (partition BY t.docname)),'/invoice/BILLINFO/CURRENT_TOTAL/text()',
extractvalue(t.update_xmldoc,'/invoice/BILLINFO/CURRENT_TOTAL') - (SUM(x.amount) over (partition BY t.docname))),'/invoice/BILLINFO/DISCOUNT_VALUE',
xmltype('<DISCOUNT_VALUE>'||(NVL(extractvalue(t.update_xmldoc,'/invoice/BILLINFO/DISCOUNT_VALUE'),0) - ROUND((SUM(x.amount) over (partition BY t.docname))/1.12,2))||'</DISCOUNT_VALUE>')), '/invoice/AR_ITEMS/ITEMS[NAME="Voice"]/USAGE_RECORDS[STREAM_NAME="NDD"]', 'DURATION_NET_DISCOUNT',
xmlelement("DURATION_NET_DISCOUNT", ROUND((SUM(x.amount) over (partition BY t.docname)*-1)/1.12,2))),'/invoice/AR_ITEMS/ITEMS[NAME="Voice"]/USAGE_RECORDS[STREAM_NAME="NDD"]','DURATION_VAT_DISCOUNT',
xmlelement("DURATION_VAT_DISCOUNT",ROUND(((SUM(x.amount) over (partition BY t.docname)*-1)/1.12)*.12,2)))
END tst
FROM xml_billrun_files t ,
xmltable('/invoice/AR_ITEMS/ITEMS/USAGE_RECORDS/SESSION_INFO'
passing t.update_xmldoc
columns chrg_duration VARCHAR2(20) path 'DURATION',
amount NUMBER path 'AMOUNT') x
WHERE seq_id = seq
AND t.docname = REPLACE(fn,'.','_HULK.')
)
WHERE rn = 1;
UPDATE xml_billrun_files a
SET update_xmldoc = xmlU
WHERE seq_id = seq
AND docname = REPLACE(fn,'.','_HULK.');
COMMIT;
END LOOP;
END IF;
END;
最佳答案
问题是 XPath 中的字符串连接。它不喜欢你做... AR_ITEMS['||lp||']/ITEMS ...
。
您可以通过 passing
子句传递 PL/SQL lp
变量的值,该子句允许使用多个逗号分隔的参数;给它一个标识符,然后直接在 XPath 中引用它。我一直坚持使用 "lp"
和 $lp
;它们不必与 PL/SQL 变量名称匹配,但如果匹配的话可能会更清楚。
XMLQuery('for $i in distinct-values(/invoice/AR_ITEMS[$lp]/ITEMS/EVENTS/BAL_IMPACTS/DISCOUNT_INFO)
where $i = "Plan499 Corp Disc"
or $i = "Plan899 Corp Disc"
or $i = "Plan1099 Corp Disc"
or $i = "Plan1599 Corp Disc"
return $i' passing original_xmldoc, cast(lp as number) as "lp" returning content ).getStringVal() sys_descr,
PL/SQL 循环索引变量 lp
是传递子句不喜欢的 pls_integer
;如果直接传递它,您会得到 ORA-00932,因此您需要将其转换为数字数据类型。
关于sql - Oracle XMLQuery 传递参数值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35647002/