使用 PostgreSql 几天,我被其新颖的功能以及效率深深吸引,我非常喜欢她!然而 PostgreSql 较稳定的版本在8.0以前通常在Unix以及Linux系统下运行,让一些普通开发人员入门很难!而同时我发觉国内开发人员不怎么愿意与别人分享成功的经验,看来传统文化“绝技不外传”的影响力依然不可小看。BOM之算法虽然非什么绝技但确实难到一些开发人员,本人一直研究MRP,在国内外BBS以及网上还没有看见谁将MRP最核心的算法公布出来,而MRP核心的核心BOM之算法也不多见。而以PostgreSql 的扩展语言plpgsql撰写BOM算法我还没有在国内外的网站上看见过,现在我将完整的BOM算法公布出来,无阶层限制。当然更好的BOM算法还有,如最终报告实现树形结构的SQL算法。此算法待我有空再发布出来。
第一步,建立两个表。第一个表存放BOM结构数据,而另外一个表存放你查询一个产品BOM报告。
--BOM 数据存放表 CREATE TABLE bomib ( ib010 char(12), --父阶 ib020 char(12), --子阶 ib030 int4 --用量 )WITH OIDS;
--测试数据 INSERT INTO BOMIB VALUES(''''01OS620000GS'''', ''''1040-1212212, 1); INSERT INTO BOMIB VALUES(''''01OS620000GS'''', ''''1041-1212212, 1); INSERT INTO BOMIB VALUES(''''01OS620000GS'''', ''''13OS-6200010, 1); INSERT INTO BOMIB VALUES(''''01OS620000GS'''', ''''13OS-6200020, 1); INSERT INTO BOMIB VALUES(''''1040-1212212'''', ''''2411-0602700, 1); INSERT INTO BOMIB VALUES(''''13OS-6200010, ''''2012-1212212, 1);
--BOM 报表存放地 CREATE TABLE bomzz ( zz010 char(12), --父阶 zz020 char(12), --子阶 zz030 int4, --用量 zz040 int8 --阶层码 )WITH OIDS;
--检查零时表是否存在的函数 CREATE OR REPLACE FUNCTION ps_temp_table("varchar") RETURNS bool AS $BODY$ DECLARE
BEGIN
perform n.nspname ,c.relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname like ''''pg_temp_%'''' AND pg_catalog.pg_table_is_visible(c.oid) AND Upper(relname) = Upper($1);
IF FOUND THEN RETURN TRUE; ELSE RETURN FALSE; END IF;
END; $BODY$ LANGUAGE ''''plpgsql'''' VOLATILE;
--BOM 展开函数 CREATE OR REPLACE FUNCTION bomia_part(bpchar) RETURNS SETOF bomzz AS $BODY$ DECLARE ENDTREE INT8; NLVL INT8; REC INT8; RESULT RECORD; BEGIN
ENDTREE:=0; NLVL:=1;
--Clear bill of material report data DELETE FROM bomzz;
--Check temp table "STACK" exists IF ps_temp_table(''''STACK'''') THEN RAISE NOTICE ''''TEMP TABLE "STACK" EXISTS!''''; ELSE CREATE TEMP TABLE STACK ( PARENT CHAR(12), PARTNO CHAR(12), USAGE INT8, LVLS INT8 ) WITHOUT OIDS ON COMMIT DELETE ROWS; END IF;
INSERT INTO STACK SELECT IB010,IB020,IB030,1 FROM BOMIB WHERE IB010=$1;
WHILE (ENDTREE=0) LOOP NLVL := NLVL + 1;
INSERT INTO STACK(LVLS,PARENT,PARTNO,USAGE) SELECT NLVL, A.IB010, A.IB020, A.IB030 FROM BOMIB A, STACK B WHERE A.IB010 =B.PARTNO AND B.LVLS= NLVL -1;
IF NOT EXISTS(SELECT PARTNO FROM STACK WHERE LVLS =NLVL) THEN ENDTREE := 1; END IF;
END LOOP;
INSERT INTO BOMZZ(ZZ010,ZZ020,ZZ030,zz040) SELECT PARENT,PARTNO,USAGE,LVLS FROM STACK;
FOR RESULT IN SELECT * FROM BOMZZ LOOP RETURN NEXT RESULT; END LOOP;
RETURN; END$BODY$ LANGUAGE ''''plpgsql'''' VOLATILE;
--使用这个函数 SELECT * FROM bomia_part(''''xxx''''); --xxx = 父阶料号
|