我尝试运行的查询是我通常只在直接 SQL 窗口(使用 PL/SQL 开发人员)中运行的查询,并带有 & 以获取提示的值。
我想在 PL/SQL 中编写一个函数/程序,它将从一个查询中提取一个值列表(也在 for 循环中使用此查询)并在第二个查询中一个接一个地运行这些值,然后返回这些值并输出他们。
我认为我很接近,但不断收到并非所有变量都绑定错误。我没有正确声明变量吗?
当我运行代码并注释掉函数 get_case_count 和函数调用时,它运行得很好。
这是代码(根据答案 1 的建议进行了更新):
declare
skunumber integer;
scounter integer;
function get_case_count (skunum integer)
return integer
is
numcases integer := 0;
begin
dbms_output.put_line('before SQL');
select total - (tcaseacp - sum(pickamt)-numlockstock-numlockloc-numlostcase-numqdcase-qainvreserve)- sum(pickamt) - sum(scratched) - sum(filled) into numcases
from
(select SKU, dscr, requant total, (retreserved+preres) pickamt, fulfilled filled,
case when trays is null then 0 else trays end trays,
case when reasoncode is null then 0 else (requested - retreserved - fulfilled - preres) end scratched,
case when totcasesacp is null then 0 else totcasesacp end tcaseacp,
case when numlockstock is null then 0 else numlockstock end numlockstock,
case when numlockloc is null then 0 else numlockloc end numlockloc,
case when totcaserec is null then 0 else totcaserec end totcaserec,
case when totcasetr is null then 0 else totcasetr end totcasetr,
case when numlostcase is null then 0 else numlostcase end numlostcase,
case when numqdcase is null then 0 else numqdcase end numqdcase,
case when qainvreserve is null then 0 else qainvreserve end qainvreserve
from
(select mat.externalidentifier SKU, mat.description dscr, rol.requestedquantity requested,
rol.fulfilledquantity fulfilled,
case when resamount is null then 0 else resamount end retreserved,
case when quant is null then 0 else quant end preres,
rol.reasoncode reasoncode
from ant.wmsretrievalorderline rol
join ant.wmsretrievalorder ro
on rol.retrievalorder_id = ro.id
join ant.wmsmaterial mat
on rol.material_id = mat.id
left join (select res.retrievalorderline_id roid,
count(res.amount) resamount
from ant.wmsreservation res
group by res.retrievalorderline_id)
on roid = rol.id
left join (select preres.retrievalorderline_id rid,
sum(preres.prereservedquantity) quant
from ant.wmsretrievalprereservation preres
group by preres.retrievalorderline_id)
on rid = rol.id
where ro.retrievalstate in (4,6,10)
) retrievalreserved
right join (select m.externalidentifier SKUS,
sum(rl.requestedquantity) requant
from ant.wmsretrievalorderline rl
join ant.wmsmaterial m
on rl.material_id = m.id
group by m.externalidentifier) requested
on SKUS = SKU
left join
(select mat.externalidentifier SKURES, sum(res.amount) qainvreserve from ant.wmsreservation res
join ant.wmsstockitem si
on res.stockitem_id = si.id
join ant.wmsmaterial mat
on mat.id = si.material_id
where res.retrievalorderline_id is null
group by mat.externalidentifier)
on SKU = SKURES
left join
(select mat.externalidentifier SKUC, sum(s.amount) totcasesacp
from ant.wmsstockitem s
join ant.wmsmaterial mat
on s.material_id = mat.id
join ant.wmsloadunit lu
on s.loadunit_id = lu.id
where s.owner = 0
and substr(lu.barcode,1,2) != 'CA'
group by mat.externalidentifier)totcases
on SKUC = SKU
left join
(select mat.externalidentifier SKUT, count(si.loadunit_id) trays from ant.wmsstockitem si
join ant.wmsloadunit lu on
lu.id = si.loadunit_id
join ant.wmsmaterial mat on
si.material_id = mat.id
where lu.loadunittype_id = '6008' and si.owner = '0'
group by mat.externalidentifier
)numtrays
on SKUT = SKU
left join
(select SKUBB, sum(qdnostock) numqdcase, sum(expstock) numexpcase
from(select SKUBB, case when inwindow = 'no' then namt+n3amt else 0 end qdnostock,
case when expired = 'yes' then amt else 0 end expstock
from(select SKUBB, case when (bbd < sysdate and (qdwin < '999') and sg != 'GOCCaustic') then 'yes' else 'no' end expired,
nvl(substr(bbd-nbbd, 7, 4), 0) datediff,case when substr(bbd-nbbd, 7, 4) > qdwin then 'no' else 'yes' end inwindow,
amt, nvl(namt, 0)namt, nvl(n3amt, 0) n3amt from
(select mat.externalidentifier SKUBB, qdwin, sg, si.bestbeforedate bbd, lead(si.bestbeforedate, 1) over (order by si.bestbeforedate asc) nbbd,
sum(si.amount) amt, lead(sum(si.amount), 1) over (order by si.bestbeforedate) namt, lead(sum(si.amount),2) over (order by si.bestbeforedate) n3amt
from ant.wmsstockitem si
join ant.wmsmaterial mat
on si.material_id = mat.id
join ant.wmsloadunit lu
on si.loadunit_id = lu.id
left join
(select distinct(rol.qdwindow) qdwin, mat.externalidentifier SKUQD, rol.shippinggroup sg
from ant.wmsretrievalorderline rol
join ant.wmsmaterial mat
on mat.id = rol.material_id
)
on SKUQD=mat.externalidentifier
where lu.loadunittype_id = '6008'
and si.owner = '0'
and mat.externalidentifier = skunum
group by mat.externalidentifier, qdwin, sg, si.bestbeforedate)
where substr(bbd-nbbd, 7, 4) is not null
))group by SKUBB)
on SKUBB = SKU
left join
(select mat.externalidentifier SKUL, sum(s.amount) numlockstock
from ant.wmsstockitem s
join ant.wmsmaterial mat
on s.material_id = mat.id
join ant.wmsloadunit lu
on s.loadunit_id = lu.id
join ant.wmslocation l
on lu.location_id = l.id
where s.owner = 0
and substr(l.name, 1, 2) in ('TS','CW')
and s.id in (select distinct ll.stockitem_id sid from
ant.wmslogisticlock ll where ll.logisticlockreason != '125')
group by mat.externalidentifier
order by SKUL)lockedstock
on SKUL = SKU
left join
(select mat.externalidentifier SKULL, sum(s.amount) numlockloc
from ant.wmsstockitem s
join ant.wmsmaterial mat
on s.material_id = mat.id
join ant.wmsloadunit lu
on s.loadunit_id = lu.id
join ant.wmslocation l
on lu.location_id = l.id
where s.owner = 0
and substr(l.name, 1, 2) in ('TS','CW')
and (l.id in
(select fa.wmslocation_id from ant.failoverlock flk
join ant.failoverarea fa
on flk.failoverarea_id = fa.id)
or lu.barcode in
(select tu.name from ant.mfstransportunit tu
join ant.mfsstoragelocation sl on tu.storagelocation_id = sl.id
where sl.id in (select mfsl.storagelocation_id
from ant.mfslogisticlock mfsl)))
group by mat.externalidentifier)lockedloc
on SKULL = SKU
left join
(select mat.externalidentifier SKUR, sum(s.amount) totcaserec
from ant.wmsstockitem s
join ant.wmsmaterial mat
on s.material_id = mat.id
join ant.wmsloadunit lu
on s.loadunit_id = lu.id
join ant.wmslocation l
on lu.location_id = l.id
where s.owner = 0
and substr(l.name, 1, 2) not in ('TS','CW', 'Ou')
and substr(l.name, 1, 6) != 'LOC_PP'
and l.name != 'LOC_GEN_LOST'
and lu.barcode like '____________________'
group by mat.externalidentifier
)
on SKUR=SKU
left join
(select mat.externalidentifier SKUTFR, sum(s.amount) totcasetr
from ant.wmsstockitem s
join ant.wmsmaterial mat
on s.material_id = mat.id
join ant.wmsloadunit lu
on s.loadunit_id = lu.id
join ant.wmslocation l
on lu.location_id = l.id
left join ant.wmslogisticlock ll
on ll.stockitem_id = s.id
where s.owner = 0
and substr(l.name, 1, 2) not in ('TS','CW', 'Ou')
and substr(l.name, 1, 6) != 'LOC_PP'
and l.name != 'LOC_GEN_LOST'
and lu.barcode like '________'
and ll.logisticlockreason = 'Initial Putaway lock for inbound'
group by mat.externalidentifier
)
on SKUTFR = SKU
left join
(select mat.externalidentifier SKULO, sum(s.amount) numlostcase
from ant.wmsstockitem s
join ant.wmsmaterial mat
on s.material_id = mat.id
join ant.wmsloadunit lu
on s.loadunit_id = lu.id
join ant.wmslocation l
on lu.location_id = l.id
where s.owner = 0
and l.name = 'LOC_GEN_LOST'
group by mat.externalidentifier
order by SKULO)lostcases
on SKULO = SKU
where SKU is not null
)
where SKU = skunum
group by SKU,dscr, total, tcaseacp, totcaserec,totcasetr,trays, numlockstock,numlockloc, numlostcase, numqdcase,qainvreserve;
dbms_output.put_line('After SQL');
return numcases;
end;
begin
skunumber := 000000;
scounter := 0;
for skutable in
(select mat.externalidentifier sku from ant.wmsstockitem si
join ant.wmsmaterial mat
on si.material_id = mat.id
join ant.wmsloadunit lu
on si.loadunit_id = lu.id
join ant.wmslocation l
on lu.location_id = l.id
where l.name = 'CWL3156')
loop
skunumber := skutable.sku;
scounter := scounter+1;
dbms_output.put_line('sku number ' || scounter || ' is ' || skunumber);
dbms_output.put_line('cases needed for ' ||skunumber|| ' is '||get_case_count(skunumber));
end loop;
end;
似乎是 skunum 变量给出了问题,但同样,我不知道该怎么做。如果有人对如何运行它有更好的建议,我将不胜感激。
提前致谢!
--UPDATE 我尝试了第一个答案建议,然后我重写了我的 SQL 并使第一行如下:
select total - (tcaseacp - sum(pickamt)-numlockstock-numlockloc-numlostcase-numqdcase-qainvreserve)- sum(pickamt) - sum(scratched) - sum(filled) into numcases
现在我得到 ORA-01722: invalid number
此数学运算中的所有值都是数值。我是否应该尝试在此周围放置另一个选择,然后尝试将 select .... 放入 numcases?我将用我的新更改更新上面的代码。