【问题标题】:Syntax error with Complex MySQL Procedure/Function复杂 MySQL 过程/函数的语法错误
【发布时间】:2022-01-12 20:49:24
【问题描述】:

我提出了一个相当复杂的查询,它根据一些输入参数计算并返回两个日期字段。这些日期值需要在包含许多其他字段的报告中进一步使用。如您所见,有 4 个输入变量和 2 个输出变量。

set @caSplit = 0.3; 
set @flSplit = 0.7; 
set @formulaForAvgUsed='useAvgOfAll'; 
set @itemNumber = 'TAB_120_IVR_POLY'; 

select 
    max(case when compCA >0 then rollingDate else current_date  end) as oosDateForCA, 
    max(case when compFL >0 then rollingDate else current_date END) as oosDateForFL 
from 
 (

select 
    items.item, items.rollingDate, perDaySalesCA, perDaySalesFL,
    items.total_items_in_ca, total_items_in_fl, flAsnItems.flASNQty, caAsnItems.caASNQty, 
    @prevDayCA := case
        when cntr = 0 then total_items_in_ca
        when greatest(@prevDayCA,0) + coalesce(caASNQty,0) = 0 then 0 
        else greatest(@prevDayCA,0) - perDaySalesCA - IF(@prevDayFL > perDaySalesFL, 0, perDaySalesFL)   + coalesce(caASNQty,0)
    end as compCA,
    @prevDayCA as caInv,
    @prevDayFL := case
        when cntr = 0 then total_items_in_fl
        when greatest(@prevDayFL,0) + coalesce(flASNQty,0) = 0 then 0
        else greatest(@prevDayFL,0) - perDaySalesFL - IF(@prevDayCA > perDaySalesCA, 0, perDaySalesCA)  + coalesce(flAsnQty, 0)
    end as compFL,
    @prevDayFL as flInv

from 
(select  @prevDayCA := -1, @prevDayFL := -1)vars, 
(
    select 
        item,  total_items_in_fl, total_items_in_ca, 
                ROUND(avgToUse * @caSplit / 30)  as perDaySalesCA,  
                ROUND(avgToUse * @flSplit / 30)  as perDaySalesFL,
                @cntr as cntr,
        DATE_ADD(current_date, INTERVAL @cntr DAY) as rollingDate,  
        @cntr := @cntr + 1 
    from 
        (
            select
                @cntr := 0
        ) vars
        join counter c
        join
        (       
        select 
            i.number as item, i.total_items_in_ca, i.total_items_in_fl,
            case when @formulaForAvgUsed = 'useNewMSA' then 
                    i.new_msa
                when @formulaForAvgUsed = 'useMSA' then 
                    i.monthly_sales_average
                when @formulaForAvgUsed = 'useWMSA' then 
                    i.weighted_monthly_sales_average
                when @formulaForAvgUsed = 'useTwoWeeks' then 
                    i.two_wks_average * 2 
                when @formulaForAvgUsed = 'useMaxAvg' then 
                    greatest(i.new_msa, i.monthly_sales_average, i.weighted_monthly_sales_average, i.two_wks_average *2)  
                when @formulaForAvgUsed = 'useAvgOfAll' then 
                    case when DATE_ADD(i.first_sold_date, INTERVAL 365 DAY) > CURRENT_DATE then 
                        (i.new_msa + i.two_wks_average *2 + i.monthly_sales_average)/3 
                    else 
                        (i.new_msa + i.two_wks_average *2 + i.monthly_sales_average+ i.weighted_monthly_sales_average)/4 
                    end    
                when @formulaForAvgUsed = 'useAvgMSAAndNewMSA' then
                        (i.new_msa + i.monthly_sales_average)/2
                when @formulaForAvgUsed = 'useAvgWMSAAndTwoWeeks' then 
                    case when DATE_ADD(i.first_sold_date, INTERVAL 365 DAY) < CURRENT_DATE then 
                        i.weighted_monthly_sales_average
                    else 
                        ( i.two_wks_average *2 + i.weighted_monthly_sales_average)/2
                    end    
                else 
                    greatest(i.new_msa, i.monthly_sales_average, i.weighted_monthly_sales_average, i.two_wks_average *2) 
                end as avgToUse                     
        from 
            item i
        where 
            i.number = @itemNumber  
    ) T
) items
        left join 
        (
            select 
                i.number, date(estimated_arrival_date) as asnDate, 
                sum((aol.loaded_quantity - aol.received_Quantity) * p.quantity) as caASNQty
            from 
                item i join asn_order_line aol on aol.item_id = i.item_id 
                join asn_order ao on ao.asn_order_id = aol.asn_order_id
                join pack p on aol.pack_id = p.pack_id
            where 
                aol.line_status = 'New' and ao.status in ('New' , 'Partial Receipt', 'Receiving', 'Partially Received') 
                and facility = 'WHSE'
                and i.number = @itemNumber
            group by 
                i.number, date(estimated_arrival_date) 
        ) caAsnItems on caAsnItems.number = items.item and caAsnItems.asnDate = rollingDate
        left join 
        (
            select 
                i.number,         
                date(estimated_arrival_date) as asnDate,
                sum((aol.loaded_quantity - aol.received_Quantity) * p.quantity) as flASNQty
            from 
                item i join asn_order_line aol on aol.item_id = i.item_id 
                join asn_order ao on ao.asn_order_id = aol.asn_order_id
                join pack p on aol.pack_id = p.pack_id
            where 
                aol.line_status = 'New' and ao.status in ('New' , 'Partial Receipt', 'Receiving', 'Partially Received') 
                and facility = 'FLOR'
                and i.number =  @itemNumber
            group by 
                i.number, date(estimated_arrival_date)
        ) flAsnItems on flAsnItems.number = items.item and flAsnItems.asnDate = rollingDate
 group by 
    rollingDate
 having
      caInv > 0 || flInv > 0 
       || rollingDate <= greatest(max(flAsnItems.asnDate), max(caAsnItems.asnDate))
order by 
    rollingDate DESC
)top;

我的意图是创建一个过程并将顶层中的值选择到输出变量中。当我尝试使用这种语法创建时使用 MySQL Workbench,它会抛出一个语法错误,但没有说明问题到底是什么。

DELIMITER // 

CREATE PROCEDURE `compute_oos_date2` (IN itemNumber VARCHAR(50), IN formulaForAvgUsed VARCHAR(50), IN caSplit FLOAT, IN flSplit FLOAT, OUT oosDateForCA DATE, OUT oosDateForFL DATE)

BEGIN
    SET @prevDayCA = -1;
    SET @prevDayFL = -1;
select 
    max(case when compCA >0 then rollingDate else current_date  end)  into oosDateForCA, 
    max(case when compFL >0 then rollingDate else current_date END) into oosDateForFL 
from 
 (

select 

    items.item, items.rollingDate, perDaySalesCA, perDaySalesFL,
    items.total_items_in_ca, total_items_in_fl, flAsnItems.flASNQty, caAsnItems.caASNQty, 
    @prevDayCA := case
        when cntr = 0 then total_items_in_ca
        when greatest(@prevDayCA,0) + coalesce(caASNQty,0) = 0 then 0 
        else greatest(@prevDayCA,0) - perDaySalesCA - IF(@prevDayFL > perDaySalesFL, 0, perDaySalesFL)   + coalesce(caASNQty,0)
    end as compCA,
    @prevDayCA as caInv,
    @prevDayFL := case
        when cntr = 0 then total_items_in_fl
        when greatest(@prevDayFL,0) + coalesce(flASNQty,0) = 0 then 0
        else greatest(@prevDayFL,0) - perDaySalesFL - IF(@prevDayCA > perDaySalesCA, 0, perDaySalesCA)  + coalesce(flAsnQty, 0)
    end as compFL,
    @prevDayFL as flInv

from 
(
    select 
        item,  total_items_in_fl, total_items_in_ca, 
                ROUND(avgToUse * caSplit / 30)  as perDaySalesCA,  
                ROUND(avgToUse * flSplit / 30)  as perDaySalesFL,
                @cntr as cntr,
        DATE_ADD(current_date, INTERVAL @cntr DAY) as rollingDate,  
        @cntr := @cntr + 1 
    from 
        (select  @cntr := 0) vars
        join counter c
        join
        (       
        select 
            i.number as item, i.total_items_in_ca, i.total_items_in_fl,
            case when formulaForAvgUsed = 'useNewMSA' then 
                    i.new_msa
                when formulaForAvgUsed = 'useMSA' then 
                    i.monthly_sales_average
                when formulaForAvgUsed = 'useWMSA' then 
                    i.weighted_monthly_sales_average
                when formulaForAvgUsed = 'useTwoWeeks' then 
                    i.two_wks_average * 2 
                when formulaForAvgUsed = 'useMaxAvg' then 
                    greatest(i.new_msa, i.monthly_sales_average, i.weighted_monthly_sales_average, i.two_wks_average *2)  
                when formulaForAvgUsed = 'useAvgOfAll' then 
                    case when DATE_ADD(i.first_sold_date, INTERVAL 365 DAY) > CURRENT_DATE then 
                        (i.new_msa + i.two_wks_average *2 + i.monthly_sales_average)/3 
                    else 
                        (i.new_msa + i.two_wks_average *2 + i.monthly_sales_average+ i.weighted_monthly_sales_average)/4 
                    end    
                when formulaForAvgUsed = 'useAvgMSAAndNewMSA' then
                        (i.new_msa + i.monthly_sales_average)/2
                when formulaForAvgUsed = 'useAvgWMSAAndTwoWeeks' then 
                    case when DATE_ADD(i.first_sold_date, INTERVAL 365 DAY) < CURRENT_DATE then 
                        i.weighted_monthly_sales_average
                    else 
                        ( i.two_wks_average *2 + i.weighted_monthly_sales_average)/2
                    end    
                else 
                    greatest(i.new_msa, i.monthly_sales_average, i.weighted_monthly_sales_average, i.two_wks_average *2) 
                end as avgToUse                     
        from 
            item i
        where 
            i.number  = itemNumber
    ) T
) items
        left join 
        (
            select 
                i.number, date(estimated_arrival_date) as asnDate, 
                sum((aol.loaded_quantity - aol.received_Quantity) * p.quantity) as caASNQty
            from 
                item i join asn_order_line aol on aol.item_id = i.item_id 
                join asn_order ao on ao.asn_order_id = aol.asn_order_id
                join pack p on aol.pack_id = p.pack_id
            where 
                aol.line_status = 'New' and ao.status in ('New' , 'Partial Receipt', 'Receiving', 'Partially Received') 
                and facility = 'WHSE'
                and i.number= itemNumber
            group by 
                i.number, date(estimated_arrival_date) 
        ) caAsnItems on caAsnItems.number = items.item and caAsnItems.asnDate = rollingDate
        left join 
        (
            select 
                i.number,         
                date(estimated_arrival_date) as asnDate,
                sum((aol.loaded_quantity - aol.received_Quantity) * p.quantity) as flASNQty
            from 
                item i join asn_order_line aol on aol.item_id = i.item_id 
                join asn_order ao on ao.asn_order_id = aol.asn_order_id
                join pack p on aol.pack_id = p.pack_id
            where 
                aol.line_status = 'New' and ao.status in ('New' , 'Partial Receipt', 'Receiving', 'Partially Received') 
                and facility = 'FLOR'
                and i.number = itemNumber
            group by 
                i.number, date(estimated_arrival_date)
        ) flAsnItems on flAsnItems.number = items.item and flAsnItems.asnDate = rollingDate
 group by 
    rollingDate
 having
      caInv > 0 || flInv > 0 
       || rollingDate <= greatest(max(flAsnItems.asnDate), max(caAsnItems.asnDate))
order by 
    rollingDate DESC
)top
END //

DELIMITER;

谁能帮忙?

【问题讨论】:

    标签: mysql procedure


    【解决方案1】:

    我想通了,加载到多个变量的语法是

    select 'abc', 'def' into var1, var2

    我之前用过

    select 'abc' into var1, 'def' into var2

    【讨论】:

      猜你喜欢
      • 2018-12-13
      • 1970-01-01
      • 1970-01-01
      • 2018-05-22
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多