一、什么是BOM交叉表

1、交叉表的定义

2、交叉表模型

二、交叉表用途

三、基于SYTELINE的交叉表生成存储过程

1、算法流程

2、存储过程

a、形成原材料对应产品的BOM列表

********ADDON7_BOMList_sp1*****************-----主函数

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ADDON7_BOMList_sp1]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[ADDON7_BOMList_sp1]
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO


CREATE PROCEDURE [ADDON7_BOMList_sp1]
(@flag  bit)
AS

if @flag=1
begin
SELECT DISTINCT item into #temp
FROM jobmatl
WHERE (job IN
          (SELECT job
         FROM item)) AND (obs_date IS NULL OR
      obs_date >= CONVERT(varchar(20), GETDATE(), 111)) AND (effect_date IS NULL OR
      effect_date <= CONVERT(varchar(20), GETDATE(), 111)) AND (item IN
          (SELECT item
         FROM item
         WHERE phantom_flag = 0))
declare @item  ItemType
declare @aitem ItemType
declare @matlqty QtyPerType
declare @serial_tracked  ListYesNotype
delete from tmpbom
declare rsta cursor for
select * from #temp  
open rsta
while 0 = 0
 begin
     fetch rsta into
  @item
         if @@fetch_status != 0
   break
declare  rstb cursor for
SELECT item.item, jobmatl.item,
      jobmatl.matl_qty_conv,item.serial_tracked 
FROM jobmatl INNER JOIN
      item ON jobmatl.job = item.job
WHERE (jobmatl.item = @item) AND (jobmatl.obs_date IS NULL OR
      jobmatl.obs_date >= CONVERT(varchar(20), GETDATE(), 111)) AND
      (jobmatl.effect_date IS NULL OR
      jobmatl.effect_date <= CONVERT(varchar(20), GETDATE(), 111))
open rstb
  while 0=0
 begin
 fetch rstb into
 @aitem,@item,@matlqty,@serial_tracked
 if @@fetch_status!=0
     break
   if @serial_tracked ='1'
    begin
    insert TmpBom (item,aitem,qty) values (@item,@aitem,@matlqty)
    end
   else
    begin
 --print @serial_tracked
 exec addon7_Bomlist_sp2 @item,@item,@aitem,@matlqty
    end  
 end
close rstb
deallocate rstb
end
drop  table #temp
close rsta
deallocate rsta
end
if @flag=0
begin
exec ADDON7_BOMList_sp3
end
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

*******ADDON7_BOMList_sp2*************----递归调用

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Addon7_Bomlist_sp2]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[Addon7_Bomlist_sp2]
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO


CREATE     Procedure addon7_Bomlist_sp2
(
  @itemk  itemtype
 , @item  itemtype
 ,@aitem  itemtype
 ,@matlqty QtyPerType
 --,@flag  bit
) as
declare @Bitem  ItemType
declare @Baitem ItemType
declare @Ditem ItemType
declare @Bmatlqty QtyPerType
declare @Bserial_tracked  ListYesNotype
--if @flag=1
  --set @Ditem=@item
if not exists(SELECT top 1 1
FROM jobmatl INNER JOIN
      item ON jobmatl.job = item.job
WHERE (jobmatl.item = @aitem) AND (jobmatl.obs_date IS NULL OR
      jobmatl.obs_date >= CONVERT(varchar(20), GETDATE(), 111)) AND
      (jobmatl.effect_date IS NULL OR
      jobmatl.effect_date <= CONVERT(varchar(20), GETDATE(), 111)))
goto endtag
declare rst cursor for
SELECT item.item, jobmatl.item,
      jobmatl.matl_qty_conv,item.serial_tracked 
FROM jobmatl INNER JOIN
      item ON jobmatl.job = item.job
WHERE (jobmatl.item = @aitem) AND (jobmatl.obs_date IS NULL OR
      jobmatl.obs_date >= CONVERT(varchar(20), GETDATE(), 111)) AND
      (jobmatl.effect_date IS NULL OR
      jobmatl.effect_date <= CONVERT(varchar(20), GETDATE(), 111))
open rst
while 0=0
 begin
 fetch rst into
 @Baitem,@Bitem,@Bmatlqty,@Bserial_tracked
 if @@fetch_status!=0
     break
   if @Bserial_tracked ='1'
      begin

      insert TmpBom (item,aitem,qty) values (@itemk,@Baitem,@matlqty*@Bmatlqty)
      end
   if @Bserial_tracked <>'1'
  begin
  close rst
  deallocate rst
  declare @sumqty  QtyPerType
  set  @sumqty=@matlqty*@Bmatlqty
  goto  nextflag
  end 
 end
 close rst
deallocate rst
nextflag:
exec addon7_Bomlist_sp2 @itemk,@bitem,@Baitem,@sumqty
endtag:

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

*******ADDON7_BOMList_sp3*************----形成交叉表

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ADDON7_BOMList_sp3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[ADDON7_BOMList_sp3]
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO


CREATE PROCEDURE [ADDON7_BOMList_sp3]
as
SELECT DISTINCT TmpBom.item, item.description into #tmpbom
FROM TmpBom INNER JOIN
      item ON TmpBom.item = item.item
ORDER BY TmpBom.item
declare @col nvarchar(30)
 ,@altstring nvarchar(255)
declare cols_all cursor local static for
  SELECT DISTINCT aitem
  FROM TmpBom
  ORDER BY aitem
  open cols_all
  while 0 = 0
  begin
      fetch cols_all into    @col
   if @@fetch_status != 0
    break
   set @altstring=N'ALTER TABLE #tmpbom ADD [' +@col +  ']  DECIMAL(18, 8)  NULL'
   exec sp_executesql @altstring
   set @altstring='update #tmpbom set [' +@col+ ']=(select sum(qty) from tmpbom where #tmpbom.item=tmpbom.item and tmpbom.aitem='''+@col+''' group by tmpbom.item,tmpbom.aitem having sum(qty)>0)'
   --set @altstring=N'UPDATE #TmpBom SET [' +@col+ '] =(select qty from #tmpbom where citem = #tmpbom_change.Item  and pitem=N'''+ @col +''')'        
   exec sp_executesql @altstring
  end
  close cols_all
  deallocate cols_all
select * from #tmpbom
drop table #tmpbom
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

四、BOM交叉表的用途