我试图运行的查询是我通常只在一个直接的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:无效号码
此数学运算中的所有值都是数值。我是否应该尝试在此处添加另一个选择,然后尝试选择....进入数字?我将使用我的新更改更新上面的代码。
答案 0 :(得分:0)
execute immediate :query_str
into :numcases
using :skunum;
这意味着query_str,numcases和skunum是绑定变量,即在PL / SQL之外声明的变量(通常在SQL * Plus中)。
对于PL / SQL变量,您应该简单地写一下:
execute immediate query_str
into numcases
using skunum;
此外,在这种情况下,不需要动态SQL。所以你可以摆脱query_str并直接编写你的查询:
select total ... into numcases
from ...
where SKU = skunum
group by ... ;