Firebird程序永远运行

时间:2014-05-20 03:50:08

标签: sql firebird firebird2.5

我只是想知道是否有人可以通过这个并告诉我哪里可能出错了,因为这个程序需要大约。运行7-8分钟:

我试图多次调整程序以提高效率,但无论我做什么,它都不会加速。

declare variable THESALEPRICE double precision;
declare variable OVERHEADCOST double precision;
declare variable THEINVOICEQTY double precision;
declare variable THENETCOST double precision;
declare variable OVERHEADCOSTLOOKUP double precision;
declare variable OVERHEADQTY double precision;
declare variable THECATEGORY varchar(99);

BEGIN
  for select 
  SALESINVOICEHEADER.CUSTOMER, 
  SALESINVOICELINES.LINECODE, 
  ITEMMASTER.ITEMDESCRIPTION, 
  SALESINVOICELINES.INVOICEUNITPRICE,  
  SALESINVOICEHEADER.INVOICENUMBER, 
  SALESINVOICELINES.INVOICEQTY, 
  SALESINVOICEHEADER.INVOICEDATE, 
  EXTRACT(WEEKDAY from SALESINVOICEHEADER.INVOICEDATE) as "SALEDAY", 
  EXTRACT(WEEK from SALESINVOICEHEADER.INVOICEDATE) as "SALEWEEK", 
  EXTRACT(MONTH from SALESINVOICEHEADER.INVOICEDATE) as "SALEMONTH", 
  EXTRACT(YEAR from SALESINVOICEHEADER.INVOICEDATE) as "SALEYEAR", 
  BOMMASTER.ITEMCODE, 
  itemmaster.ADDITIONALFIELD_4 as "PRODUCTIONLINE", 
  ITEMMASTER.ITEMCATEGORY 
  from 
  SALESINVOICEHEADER, 
  SALESINVOICELINES, 
  ITEMMASTER, 
  BOMMASTER 
  where 
  salesinvoiceheader.invoicedate >= :DATEFROM and
  salesinvoiceheader.invoicedate <= :DATETO and 
  (ITEMMASTER.ITEMCATEGORY = 'FC' or ITEMMASTER.ITEMCATEGORY = 'WV') and 
  BOMMASTER.ITEMCODE = SALESINVOICELINES.LINECODE and 
  ITEMMASTER.ITEMCODE = SALESINVOICELINES.LINECODE and 
  SALESINVOICEHEADER.INVOICENUMBER = SALESINVOICELINES.INVOICENUMBER 
  order by 
  ITEMMASTER.ITEMCATEGORY, UPPER(ITEMMASTER.ITEMDESCRIPTION) 
  into 
  :CUSTOMER, :PRODUCTCODE, :PRODUCTDESC, :THESALEPRICE, :INVOICENUMBER, :THEINVOICEQTY, :SALEDATE, :SALEDAY, :SALEWEEK, :SALEMONTH, :SALEYEAR, :BOMITEMCODE, :PRODUCTIONLINE, :ITEMCATEGORY   
  do 
  begin
 SALEPRICE = :THESALEPRICE;
 INVOICEQTY = :THEINVOICEQTY;
 THENETCOST = NULL;

 SALETOTAL = :THESALEPRICE * :THEINVOICEQTY;

 CUSTOMERGROUP = NULL;
 PRICELEVEL = NULL;
 OVERRIDEPRICELEVEL = NULL;

 select first 1 
 customermaster.additionalfield_1 as "CUSTOMERGROUP", 
 customermaster.PRICELEVEL, 
 customermaster.OVERRIDEPRICELEVEL 
 from 
 CUSTOMERMASTER 
 where 
 CUSTOMERMASTER.customer = :CUSTOMER
 into 
 :CUSTOMERGROUP, :PRICELEVEL, :OVERRIDEPRICELEVEL;

 select first 1 
 itemcosthistory.NEWCOST 
 from 
 itemcosthistory 
 where 
 itemcosthistory.ITEMCODE = :PRODUCTCODE and 
 (itemcosthistory.COSTCHANGEREASON = 'BOM Cost Rollup' or itemcosthistory.COSTCHANGEREASON like 'Purchase%') and 
 itemcosthistory.COSTCHANGEDATE <= :SALEDATE and 
 itemcosthistory.COSTCHANGEDATE >= '2012-12-31' and 
 itemcosthistory.COSTTYPE = 'Standard' and 
 itemcosthistory.NEWCOST > 0 
 order by 
 itemcosthistory.sysdatecreated desc
 into 
 :THENETCOST;

 if (:THENETCOST is null OR :THENETCOST = 0) then 
 begin
   select first 1
 itemcosthistory.NEWCOST 
 from 
 itemcosthistory 
 where 
 itemcosthistory.ITEMCODE = :PRODUCTCODE and 
 (itemcosthistory.COSTCHANGEREASON = 'BOM Cost Rollup' or itemcosthistory.COSTCHANGEREASON like 'Purchase%') and 
 itemcosthistory.COSTCHANGEDATE >= '2012-12-31' and 
 itemcosthistory.COSTTYPE = 'Standard' and 
 itemcosthistory.NEWCOST > 0 
 order by 
 itemcosthistory.sysdatecreated desc 
 into 
 :THENETCOST; 
 end 

 if (:THENETCOST is null OR :THENETCOST = 0) then 
 begin 
   select first 1
 itemcosthistory.NEWCOST 
 from 
 itemcosthistory 
 where 
 itemcosthistory.ITEMCODE = :PRODUCTCODE and 
 (itemcosthistory.COSTCHANGEREASON = 'BOM Cost Rollup' or itemcosthistory.COSTCHANGEREASON like 'Purchase%') and 
 itemcosthistory.COSTTYPE = 'Standard' and 
 itemcosthistory.NEWCOST > 0 
 order by 
 itemcosthistory.sysdatecreated desc 
 into 
 :THENETCOST; 
 END

 NETCOST = :THENETCOST * :THEINVOICEQTY;

 NETPROFIT = :SALETOTAL - :NETCOST;

 if (:NETCOST = 0 or :SALETOTAL = 0) 
 then
 begin
   if (:NETCOST = 0)
   then
   begin
     NPPERCENTAGE = 100;
   end
   else if (:SALETOTAL = 0)
   then
   begin
     NPPERCENTAGE = -100;
   end
 end
 else
 begin 
   if (:NETPROFIT = 0) then 
   begin
        NPPERCENTAGE = 0;
   end
   else
   begin 
        NPPERCENTAGE = (:NETPROFIT / :SALETOTAL) * 100;
   end
 end

 select 
 first 1 DESCRIPTORMASTER.STANDARDCOST 
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.DESCRIPTORDESCRIPTION = 'OVERHEAD COST PER UNIT' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE in (
 select 
 BOMLINES.LINECODE 
 from 
 BOMLINES 
 where 
 BOMLINES.ITEMCODE = :PRODUCTCODE) 
 into 
 :OVERHEADCOSTLOOKUP;

 if (:OVERHEADCOSTLOOKUP is null) 
 then
 begin
   OVERHEADCOSTLOOKUP = 0; 
 end

 CHKOHCL = :OVERHEADCOSTLOOKUP;

 select 
 first 1 BOMLINES.PERQTY 
 from 
 BOMLINES 
 where 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 BOMLINES.LINEDESCRIPTION = 'OVERHEAD COST PER UNIT' 
 into 
 :OVERHEADQTY;

 CHKOHQTY = :OVERHEADQTY;

 if (:OVERHEADQTY is null) 
 then
 begin
   OVERHEADQTY = 0;
 end 

 OVERHEADCOST = (:OVERHEADCOSTLOOKUP * :OVERHEADQTY) * :INVOICEQTY;

 GROSSCOST = :NETCOST - :OVERHEADCOST;

 GROSSPROFIT = :SALETOTAL - :GROSSCOST;

 if (:GROSSCOST = 0 or :SALETOTAL = 0) 
 then
 begin
   if (:GROSSCOST = 0)
   then
   begin
     GPPERCENTAGE = 100;
   end
   else if (:SALETOTAL = 0)
   then
   begin
     GPPERCENTAGE = -100;
   end
 end
 else
 begin 
  if (:GROSSPROFIT = 0) then 
   begin
        GPPERCENTAGE = 0;
   end
   else
   begin
        GPPERCENTAGE = (:GROSSPROFIT / :SALETOTAL) * 100;
   end
 end
 INGREDIENTCODE = NULL;
 INGREDIENTDESC = NULL;

 select 
 first 1 
 LINECODE, 
 LINEDESCRIPTION 
 from 
 BOMLINES 
 where BOMLINES.ITEMCODE = :PRODUCTCODE and 
 (BOMLINES.LINEUNIT = 'Unit' or BOMLINES.LINEUNIT = 'Kg' or BOMLINES.LINEUNIT = 'Each') and 
 BOMLINES.codetype = 'Item Code' 
 into 
 :INGREDIENTCODE, :INGREDIENTDESC;

 select 
 CASE when SUM(LABOURMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(LABOURMASTER.STANDARDCOST * BOMLINES.PERQTY) END 
 from 
 LABOURMASTER, 
 BOMLINES  
 where 
 LABOURMASTER.ADDITIONALFIELD_2 = 'Assembly Labour' and 
 LABOURMASTER.LABOURCODE = BOMLINES.LINECODE and 
 BOMLINES.ITEMCODE = :PRODUCTCODE
 into 
 :ASSEMBLYLABOUR;

 ASSEMBLYLABOUR = :ASSEMBLYLABOUR * :THEINVOICEQTY;

 select 
 CASE when SUM(LABOURMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(LABOURMASTER.STANDARDCOST * BOMLINES.PERQTY) END 
 from 
 LABOURMASTER, 
 BOMLINES  
 where 
 LABOURMASTER.ADDITIONALFIELD_2 = 'Line Labour' and 
 LABOURMASTER.LABOURCODE = BOMLINES.LINECODE and 
 BOMLINES.ITEMCODE = :PRODUCTCODE
 into 
 :LINELABOUR;

 LINELABOUR = :LINELABOUR * :THEINVOICEQTY;

 select 
 CASE when SUM(LABOURMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(LABOURMASTER.STANDARDCOST * BOMLINES.PERQTY) END 
 from 
 LABOURMASTER, 
 BOMLINES  
 where 
 LABOURMASTER.ADDITIONALFIELD_2 = 'Indirect Labour' and 
 LABOURMASTER.LABOURCODE = BOMLINES.LINECODE and 
 BOMLINES.ITEMCODE = :PRODUCTCODE
 into 
 :INDIRECTLABOUR;

 INDIRECTLABOUR = :INDIRECTLABOUR * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Local Delivery' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :LOCALDELIVERY;

 LOCALDELIVERY = :LOCALDELIVERY * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Line Haulage' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :LINEHAULAGE;

 LINEHAULAGE = :LINEHAULAGE * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Industrial Local Delivery' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :INDUSTRIALLOCALDELIVERY;

 INDUSTRIALLOCALDELIVERY = :INDUSTRIALLOCALDELIVERY * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Market Truck' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :MARKETTRUCK;

 MARKETTRUCK = :MARKETTRUCK * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Maintenance' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :MAINTENANCE;

 MAINTENANCE = :MAINTENANCE * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Interstate Metro Freight' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :INTERSTATEMETROFREIGHT;

 INTERSTATEMETROFREIGHT = :INTERSTATEMETROFREIGHT * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Loyalty Programme / Discounts' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :LOYALTYANDDISCOUNTS;

 LOYALTYANDDISCOUNTS = :LOYALTYANDDISCOUNTS * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Overhead' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :OVERHEAD;

 OVERHEAD = :OVERHEAD * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Pallet Hire' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :PALLETHIRE;

 PALLETHIRE = :PALLETHIRE * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Purchase' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :PURCHASE;

 PURCHASE = :PURCHASE * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Quality' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :QUALITY;

 QUALITY = :QUALITY * :THEINVOICEQTY;

 select 
 CASE when SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) is null then 0 else SUM(DESCRIPTORMASTER.STANDARDCOST * BOMLINES.PERQTY) END  
 from 
 DESCRIPTORMASTER, 
 BOMLINES  
 where 
 DESCRIPTORMASTER.ADDITIONALFIELD_2 = 'Stores' and 
 BOMLINES.ITEMCODE = :PRODUCTCODE and 
 DESCRIPTORMASTER.DESCRIPTORCODE = BOMLINES.LINECODE
 into 
 :STORES;

 STORES = :STORES * :THEINVOICEQTY;

 WRITEOFFCOST = NULL;
 THECATEGORY = NULL;

 select 
 itemcategory 
 from 
 itemmaster where 
 itemmaster.itemcode = :PRODUCTCODE 
 into 
 :THECATEGORY;
 if (:THECATEGORY = 'FC') then 
 begin 
       WRITEOFFCOST = :GROSSPROFIT + :STORES + :PURCHASE + :PALLETHIRE + :LOYALTYANDDISCOUNTS + :INTERSTATEMETROFREIGHT + :INDUSTRIALLOCALDELIVERY + :LINEHAULAGE + :LOCALDELIVERY;
 end 
 else 
 begin 
       WRITEOFFCOST = :GROSSPROFIT + :STORES + :QUALITY + :PURCHASE + :PALLETHIRE + :LOYALTYANDDISCOUNTS + :INTERSTATEMETROFREIGHT + :MAINTENANCE + :INDUSTRIALLOCALDELIVERY + :LINEHAULAGE + :LOCALDELIVERY + :INDIRECTLABOUR + :LINELABOUR + :ASSEMBLYLABOUR;
 end 

 SUSPEND;
  end
END

1 个答案:

答案 0 :(得分:0)

在第一个选择查询中,您将交叉连接表,创建一个包含4个表的笛卡尔积。仅此一项是非常昂贵的操作。

另请注意,ORDER BY需要大量使用服务器资源。