[MSSQL]BOM反查

本文介绍了一种使用SQL解决ECN变更中查询物料上级半成品或顶层成品的方法,通过示例代码展示了如何利用数据库操作实现BOM反查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通常我们会写一些展BOM的程序,用游标实现。但是我们在做ECN变更的时候,经常需要查询一个物料的上级半成品或者顶层的成品有哪些?

下面SQL就是解决这个问题的方法之一:

1.现在有一个BOM表(表名:ProductStructures),有两个字段:cPSPCode(子件对应的母件编号),cPSCode(子件编号),举例数据如下:
SQL code
/*
cPSPCode cPSCode
   A       B
   B       C
   AA      BB
   BB      C
   AAA     BBB
   BBB      C
*/



2.由于一个子件如上的C可以对应多个母件,现想求一自定义函数,当输入C时反查出其对应的上级母件至最顶层母件,要求得出的结果如下:
SQL code
/*
cPSPCode cPSCode
   C       BBB
   BBB     AAA
    C       BB
   BB       AA
    C        B
    B        A
*/






-------------------------------
--  Author: liangCK 小梁
---------------------------------
 
--> 生成测试数据: [tb]
IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
CREATE TABLE [tb] (cPSPCode VARCHAR(3),cPSCode VARCHAR(3))
INSERT INTO [tb]
SELECT 'A','B' UNION ALL
SELECT 'B','C' UNION ALL
SELECT 'AA','BB' UNION ALL
SELECT 'BB','C' UNION ALL
SELECT 'AAA','BBB' UNION ALL
SELECT 'BBB','C'

--SQL查询如下:

GO

CREATE FUNCTION dbo.GetPSCode(@cPSCode VARCHAR(10))
    RETURNS @t TABLE(cPSCode VARCHAR(10),
                     cPSPCode VARCHAR(10),
                     Sort VARCHAR(1000),
                     level INT)
AS
BEGIN
    DECLARE @level INT;
    SET @level = 1;
    
    INSERT @t
        SELECT
            cPSCode,
            cPSPCode,
            cPSPCode,
            @level
        FROM tb 
        WHERE cPSCode = @cPSCode;
        
    WHILE @@ROWCOUNT>0
      BEGIN
          SET @level=@level+1;
          
          INSERT @t
              SELECT
                  B.cPSCode,
                  B.cPSPCode,
                  A.Sort + '.' + B.cPSPCode,
                  @level
              FROM @t AS A
                  JOIN tb AS B
                      ON A.cPSPCode=B.cPSCode
                          AND A.level=@level-1;
      END
    RETURN
END
GO

SELECT cPSCode,cPSPCode FROM dbo.GetPSCode('C') ORDER BY Sort

GO
DROP TABLE tb;
DROP FUNCTION dbo.GetPSCode

/*
cPSCode    cPSPCode
---------- ----------
C          B
B          A
C          BB
BB         AA
C          BBB
BBB        AAA

(6 行受影响)
*/
用2005就比较简单了

-->> Author:  让你望见影子的墙(HEROWANG)生成测试数据  Date:2009-04-17 22:30:27
IF OBJECT_ID('tb') IS NOT NULL 
    DROP TABLE tb
Go
CREATE TABLE tb(cpspcode NVARCHAR(3),cpscode NVARCHAR(3))
Go
INSERT INTO tb
 SELECT 'A','B' UNION ALL
 SELECT 'B','C' UNION ALL
 SELECT 'AA','BB' UNION ALL
 SELECT 'BB','C' UNION ALL
 SELECT 'AAA','BBB' UNION ALL
 SELECT 'BBB','C' 
GO

SELECT     * FROM    TB
;
with 
wang as (select row=row_number() over (order by getdate()),* from tb where cpscode='c'     
          union all
         select wang.row ,tb.*from tb ,wang where tb.cpscode =wang.cpspcode 
 )

select cpscode,cpspcode from wang
order by row

cpscode    cpspcode
C    B
B    A
BB    AA
C    BB
C    BBB
BBB    AAA


 

### ABAP BOM 反查函数实现 在 SAP 系统中,对于物料清单 (Bill of Material, BOM) 的反向找通常涉及递归算法来追踪物料的使用情况。具体来说,在ABAP环境中可以通过调用`CS_WHERE_USED_MAT`函数模块并结合自定义逻辑完成这一操作。 当执行BOM反查时,程序会先收集底层或中间层物料至内部表`gt_mast`[^1]。之后通过调用`CS_WHERE_USED_MAT`函数模块尝试定位这些物料在其上级组件中的位置;然而需要注意的是此函数仅能处理单级追溯任务,因此为了全面覆盖整个产品结构树,则需采用递归方式重复上述过程直至达到顶层成品或是无法再找到更高级别的父项为止。 在此过程中,每当成功识别出某物料属于最高级别(即不存在更高层次的应用场景),则设置特定标志位为`X`以标记该记录已完成分析。随后遍历所有未被标记过的条目继续进行下一轮迭代直到全部节点均被打上结束标签。最后一步是对所得结果集实施去重处理从而获得精简后的有效信息集合。 下面是一个简单的伪代码示例用于说明如何构建这样一个递归式的BOM反查功能: ```abap DATA: lt_materials TYPE TABLE OF mara, ls_material LIKE LINE OF lt_materials. FIELD-SYMBOLS: <fs_mat> LIKE LINE OF lt_materials. * 假设lt_materials已经包含了初始要询的一批物料编号... LOOP AT lt_materials ASSIGNING FIELD-SYMBOL(<fs_mat>). PERFORM check_where_used USING <fs_mat>-matnr. ENDLOOP. FORM check_where_used USING iv_material. DATA: lv_top_flag TYPE char1 VALUE space, lt_superiors TYPE TABLE OF rsdms_stru. * 调用标准FM CS_WHERE_USED_MAT 来获取当前物料的直接上级们 CALL FUNCTION 'CS_WHERE_USED_MAT' EXPORTING matnr = iv_material IMPORTING top_level = lv_top_flag TABLES superiors = lt_superiors EXCEPTIONS OTHERS = 1. IF sy-subrc EQ 0 AND lv_top_flag NE 'X'. LOOP AT lt_superiors INTO DATA(ls_superior). APPEND ls_superior TO gt_all_results. "假设这是全局变量用来存储所有的发现 * 对每一个新发现的上级再次发起同样的检流程 PERFORM check_where_used USING ls_superior-matnr. DELETE FROM gt_all_results WHERE NOT top_mark = 'X'. "清理掉那些已经被确认不是顶级成员的数据行 ENDLOOP. ELSEIF lv_top_flag = 'X'. MODIFY gt_all_results SETTING top_mark = 'X' WHERE matnr = iv_material. ENDIF. ENDFORM. ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值