0

我尝试运行的查询是我通常只在直接 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?我将用我的新更改更新上面的代码。

4

1 回答 1

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 ... ;
于 2013-08-30T22:03:23.430 回答