数据表:
drop index IX_PM_BOM_1;
drop table T_PM_BOM;
/*==============================================================*/
/* Table: T_PM_BOM */
/*==============================================================*/
create table T_PM_BOM (
ID CHAR(32) not null,
CorpId CHAR(32) not null,
InventoryId CHAR(32) not null,
CreatorId CHAR(32) not null,
CreateTime DATE null default CURRENT_DATE,
LastOperatorId CHAR(32) null,
LastOperateTime TIMESTAMP null,
GeneralMethod INT2 null default 0,
Remark VARCHAR(200) null,
Def1 VARCHAR(50) null,
Def2 VARCHAR(50) null,
Def3 VARCHAR(50) null,
Def4 VARCHAR(50) null,
Def5 VARCHAR(50) null,
Def6 VARCHAR(100) null,
Def7 VARCHAR(100) null,
Def8 VARCHAR(100) null,
Def9 VARCHAR(100) null,
Def10 VARCHAR(100) null,
IsClose CHAR(1) null,
CloseDate DATE null,
constraint PK_T_PM_BOM primary key (ID)
);
comment on column T_PM_BOM.CreatorId is
'默认为当前登录用户';
comment on column T_PM_BOM.CreateTime is
'默认为当前系统日期';
comment on column T_PM_BOM.GeneralMethod is
'0-自制
1-参照:单据数据由用户手工参照上游单据数据得到,用户可以除增行以外的操作,单据关键字段不可以编辑;
2-推式保存:单据数据由上游单据审核时自动生成,用户可以对单据进行提交、审核、弃审操作,但不能进行修改、删除操作 ;删除操作由上游单据弃审时进行
3-推式审核:单据数据由上游单据审核时自动生成,用户只能对单据时行浏览,不能进行修改、弃审操作,弃审、删除操作由上游单据进行弃审时进行;
';
comment on column T_PM_BOM.IsClose is
'1--是,0--否';
comment on column T_PM_BOM.CloseDate is
'客户冻结时写入';
/*==============================================================*/
/* Index: IX_PM_BOM_1 */
/*==============================================================*/
create index IX_PM_BOM_1 on T_PM_BOM (
CorpId,
InventoryId,
CreatorId,
CreateTime,
LastOperatorId
);
drop index IX_PM_BOM_B_2;
drop index IX_PM_BOM_B_1;
drop table T_PM_BOM_B;
/*==============================================================*/
/* Table: T_PM_BOM_B */
/*==============================================================*/
create table T_PM_BOM_B (
Id CHAR(32) not null,
BOMId CHAR(32) not null,
RowIndex INT4 not null,
InventoryId CHAR(32) not null,
InventoryClassId CHAR(10) null,
AuxiMeasUnitId CHAR(32) null,
AuxiMeasNum DECIMAL(20,8) null,
MeasConvRate DECIMAL(20,8) null,
MainMeasUnitId CHAR(32) not null,
Num DECIMAL(20,8) not null,
Remark 100 null,
Def1 VARCHAR(50) null,
Def2 VARCHAR(50) null,
Def3 VARCHAR(50) null,
Def4 VARCHAR(50) null,
Def5 VARCHAR(50) null,
Def6 VARCHAR(100) null,
Def7 VARCHAR(100) null,
Def8 VARCHAR(100) null,
Def9 VARCHAR(100) null,
Def10 VARCHAR(100) null,
constraint PK_T_PM_BOM_B primary key ()
);
comment on column T_PM_BOM_B.InventoryClassId is
'编辑存货时自动带出,不可编辑';
comment on column T_PM_BOM_B.AuxiMeasUnitId is
'编辑存货时自动带出,不可编辑';
comment on column T_PM_BOM_B.MeasConvRate is
'编辑存货时自动带出,不可编辑';
comment on column T_PM_BOM_B.MainMeasUnitId is
'编辑存货时自动带出,不可编辑';
/*==============================================================*/
/* Index: IX_PM_BOM_B_1 */
/*==============================================================*/
create index IX_PM_BOM_B_1 on T_PM_BOM_B (
BOMId
);
/*==============================================================*/
/* Index: IX_PM_BOM_B_2 */
/*==============================================================*/
create index IX_PM_BOM_B_2 on T_PM_BOM_B (
InventoryId
);
CTE循环以展开所有的BOM结构
DECLARE @tb TABLE
(
InvName NVARCHAR(100),ParentName NVARCHAR(100),InventoryId BIGINT ,ParentInventoryId BIGINT
)
INSERT @tb SELECT C.InvName, D.InvName AS ParentName, B.InventoryId, A.InventoryId AS ParentInventoryId
FROM dbo.T_PM_BOM AS A INNER JOIN dbo.T_PM_BOM_B AS B ON A.ID = B.BOMId INNER JOIN
dbo.T_BD_INVENTORYDOC AS C ON B.InventoryId =C.Id INNER JOIN
dbo.T_BD_INVENTORYDOC AS D ON A.InventoryId = D.Id
;WITH tb AS
(
SELECT *,0 as lvl /*展开层次*/ FROM @tb WHERE ParentInventoryId = 4572366130946467167
UNION ALL
SELECT a.*,b.lvl+1 FROM @tb a /*原表*/ JOIN tb b /*CTE*/ ON a.ParentInventoryId = b.InventoryId /*原表父项等于CTE子项*/
)
SELECT * FROM tb ORDER BY lvl;
判断BOM死循环
CREATE TABLE #TA(id decimal(18, 0) IDENTITY(1,1) NOT NULL,item_code varchar(50),item_code_d varchar(50),item_name NVARCHAR(100),ParentName NVARCHAR(100))
INSERT INTO #TA(item_code,item_code_d,item_name,ParentName)
SELECT B.InventoryId, A.InventoryId AS ParentInventoryId ,C.InvName, D.InvName AS ParentName FROM dbo.T_PM_BOM AS A INNER JOIN dbo.T_PM_BOM_B AS B ON A.ID = B.BOMId INNER JOIN dbo.T_BD_INVENTORYDOC AS C ON B.InventoryId =C.Id INNER JOIN dbo.T_BD_INVENTORYDOC AS D ON A.InventoryId = D.Id WHERE A.InventoryId='8368360367314946782'
--SELECT * FROM #TA
--创建临时表,用来存放符合条件的数据
CREATE TABLE #TV(item_code varchar(50),item_name NVARCHAR(100))
--查询SQL
DECLARE @L_CNT int
DECLARE @R_CNT int
DECLARE @ITEM_CODE VARCHAR(50)
DECLARE @ITEM_CODE_D VARCHAR(50)
DECLARE @ITEM_NAME NVARCHAR(100)
DECLARE @ParentName NVARCHAR(100)
SELECT @L_CNT = 0
SELECT @R_CNT = 0
WHILE EXISTS(SELECT ID FROM #TA WHERE ID > @R_CNT)
BEGIN
SELECT @R_CNT = MIN(ID) FROM #TA WHERE ID > @R_CNT
SET @L_CNT = @R_CNT
WHILE EXISTS(SELECT B.ID FROM #TA AS A,#TA AS B WHERE A.item_code_d = B.item_code AND B.id >@L_CNT AND A.ID = @R_CNT )
BEGIN
SELECT @L_CNT = MIN(B.ID) FROM #TA AS A,#TA AS B WHERE A.item_code_d = B.item_code AND B.id >@L_CNT AND A.ID = @R_CNT
SELECT @ITEM_CODE = A.ITEM_CODE,@ITEM_CODE_D = B.ITEM_CODE_D,@ITEM_NAME=A.item_name,@ParentName=A.ParentName FROM #TA AS A,#TA AS B WHERE A.item_code_d = B.item_code AND A.ID = @R_CNT AND B.ID = @L_CNT
IF @ITEM_CODE = @ITEM_CODE_D
BEGIN
INSERT INTO #TV VALUES(@ITEM_CODE,@ITEM_NAME)
END
ELSE IF NOT EXISTS(SELECT 1 FROM #TA WHERE ITEM_CODE = @ITEM_CODE AND ITEM_CODE_D = @ITEM_CODE_D )
BEGIN
INSERT INTO #TA VALUES(@ITEM_CODE,@ITEM_CODE_D,@ITEM_NAME,@ParentName)
END
END
END
--查询数据
SELECT * FROM #TV;
GO
DROP TABLE #TA,#TV;
c#语句递归展开BOM结构
private void expansionBom(string InventoryId, SQLBuilder mSQLBuilder,List<string> alist)
{
string where = string.Format("A.InventoryId={0}", LibStringBuilder.GetValueString(InventoryId));
string sql = mSQLBuilder.GetQuerySQL("B.InventoryId", where);
LibDataTable mLibDataTable = this.DataAccess.ExecuteDataTable(sql);
foreach (DataRow dr in mLibDataTable.Rows)
{
alist.Add(dr["InventoryId"].ToString());
expansionBom(dr["InventoryId"].ToString(), mSQLBuilder, alist);
}
}