/* 用途: 1. 为材料出入库和库存表补充 WarehouseId 字段。 2. 将历史 WarehouseCode 中保存的仓库名称/主键统一回填到 WarehouseId。 3. 库存表按 项目+材料主编码+仓库主键 合并重复库存。 执行前建议先备份数据库,并先执行最后的“未匹配检查”确认是否存在重名或缺失仓库。 */ SET XACT_ABORT ON; BEGIN TRAN; IF COL_LENGTH('dbo.Tw_InOutPlanMaster', 'WarehouseId') IS NULL BEGIN ALTER TABLE dbo.Tw_InOutPlanMaster ADD WarehouseId NVARCHAR(50) NULL; END; IF COL_LENGTH('dbo.Tw_InputMaster', 'WarehouseId') IS NULL BEGIN ALTER TABLE dbo.Tw_InputMaster ADD WarehouseId NVARCHAR(50) NULL; END; IF COL_LENGTH('dbo.Tw_OutputMaster', 'WarehouseId') IS NULL BEGIN ALTER TABLE dbo.Tw_OutputMaster ADD WarehouseId NVARCHAR(50) NULL; END; IF COL_LENGTH('dbo.Tw_MaterialStock', 'WarehouseId') IS NULL BEGIN ALTER TABLE dbo.Tw_MaterialStock ADD WarehouseId NVARCHAR(50) NULL; END; IF EXISTS ( SELECT 1 FROM dbo.Base_Warehouse GROUP BY ProjectId, WarehouseName HAVING COUNT(1) > 1 ) BEGIN THROW 51000, N'同一项目存在重名仓库,历史 WarehouseCode 名称数据无法唯一回填,请先处理 Base_Warehouse 重名数据。', 1; END; /* 历史数据中 WarehouseCode 可能保存仓库名称,也可能已经保存 WarehouseId,这里两种都兼容。 */ UPDATE m SET m.WarehouseId = w.WarehouseId, m.WarehouseCode = w.WarehouseName FROM dbo.Tw_InOutPlanMaster AS m INNER JOIN dbo.Base_Warehouse AS w ON w.ProjectId = m.ProjectId AND (w.WarehouseId = m.WarehouseCode OR w.WarehouseName = m.WarehouseCode OR w.WarehouseId = m.WarehouseId) WHERE ISNULL(m.WarehouseId, '') <> w.WarehouseId OR ISNULL(m.WarehouseCode, '') <> w.WarehouseName; UPDATE m SET m.WarehouseId = w.WarehouseId, m.WarehouseCode = w.WarehouseName FROM dbo.Tw_InputMaster AS m INNER JOIN dbo.Base_Warehouse AS w ON w.ProjectId = m.ProjectId AND (w.WarehouseId = m.WarehouseCode OR w.WarehouseName = m.WarehouseCode OR w.WarehouseId = m.WarehouseId) WHERE ISNULL(m.WarehouseId, '') <> w.WarehouseId OR ISNULL(m.WarehouseCode, '') <> w.WarehouseName; UPDATE m SET m.WarehouseId = w.WarehouseId, m.WarehouseCode = w.WarehouseName FROM dbo.Tw_OutputMaster AS m INNER JOIN dbo.Base_Warehouse AS w ON w.ProjectId = m.ProjectId AND (w.WarehouseId = m.WarehouseCode OR w.WarehouseName = m.WarehouseCode OR w.WarehouseId = m.WarehouseId) WHERE ISNULL(m.WarehouseId, '') <> w.WarehouseId OR ISNULL(m.WarehouseCode, '') <> w.WarehouseName; UPDATE s SET s.WarehouseId = w.WarehouseId, s.WarehouseCode = w.WarehouseName FROM dbo.Tw_MaterialStock AS s INNER JOIN dbo.Base_Warehouse AS w ON w.ProjectId = s.ProjectId AND (w.WarehouseId = s.WarehouseCode OR w.WarehouseName = s.WarehouseCode OR w.WarehouseId = s.WarehouseId) WHERE ISNULL(s.WarehouseId, '') <> w.WarehouseId OR ISNULL(s.WarehouseCode, '') <> w.WarehouseName; /* 回填后,历史上同一仓库可能因“名称”和“主键”各有一条库存记录,这里合并为一条。 */ IF OBJECT_ID('tempdb..#StockMerge') IS NOT NULL BEGIN DROP TABLE #StockMerge; END; SELECT ProjectId, PipeLineMatCode, WarehouseId, MIN(Id) AS KeepId, SUM(ISNULL(StockNum, 0)) AS TotalStock INTO #StockMerge FROM dbo.Tw_MaterialStock WHERE WarehouseId IS NOT NULL GROUP BY ProjectId, PipeLineMatCode, WarehouseId HAVING COUNT(1) > 1; UPDATE s SET s.StockNum = m.TotalStock FROM dbo.Tw_MaterialStock AS s INNER JOIN #StockMerge AS m ON m.KeepId = s.Id; DELETE s FROM dbo.Tw_MaterialStock AS s INNER JOIN #StockMerge AS m ON m.ProjectId = s.ProjectId AND m.PipeLineMatCode = s.PipeLineMatCode AND m.WarehouseId = s.WarehouseId AND s.Id <> m.KeepId; IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_Tw_InOutPlanMaster_Project_WarehouseId' AND object_id = OBJECT_ID('dbo.Tw_InOutPlanMaster')) BEGIN CREATE INDEX IX_Tw_InOutPlanMaster_Project_WarehouseId ON dbo.Tw_InOutPlanMaster(ProjectId, WarehouseId); END; IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_Tw_InputMaster_Project_WarehouseId' AND object_id = OBJECT_ID('dbo.Tw_InputMaster')) BEGIN CREATE INDEX IX_Tw_InputMaster_Project_WarehouseId ON dbo.Tw_InputMaster(ProjectId, WarehouseId); END; IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_Tw_OutputMaster_Project_WarehouseId' AND object_id = OBJECT_ID('dbo.Tw_OutputMaster')) BEGIN CREATE INDEX IX_Tw_OutputMaster_Project_WarehouseId ON dbo.Tw_OutputMaster(ProjectId, WarehouseId); END; IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_Tw_MaterialStock_Project_Material_WarehouseId' AND object_id = OBJECT_ID('dbo.Tw_MaterialStock')) BEGIN CREATE INDEX IX_Tw_MaterialStock_Project_Material_WarehouseId ON dbo.Tw_MaterialStock(ProjectId, PipeLineMatCode, WarehouseId); END; COMMIT TRAN; /* 未匹配检查:这些记录需要人工确认仓库名称是否错误、是否重名或是否缺少 Base_Warehouse 数据。 */ SELECT 'Tw_InOutPlanMaster' AS TableName, Id, ProjectId, WarehouseCode, WarehouseId FROM dbo.Tw_InOutPlanMaster WHERE ISNULL(WarehouseCode, '') <> '' AND ISNULL(WarehouseId, '') = '' UNION ALL SELECT 'Tw_InputMaster' AS TableName, Id, ProjectId, WarehouseCode, WarehouseId FROM dbo.Tw_InputMaster WHERE ISNULL(WarehouseCode, '') <> '' AND ISNULL(WarehouseId, '') = '' UNION ALL SELECT 'Tw_OutputMaster' AS TableName, Id, ProjectId, WarehouseCode, WarehouseId FROM dbo.Tw_OutputMaster WHERE ISNULL(WarehouseCode, '') <> '' AND ISNULL(WarehouseId, '') = '' UNION ALL SELECT 'Tw_MaterialStock' AS TableName, Id, ProjectId, WarehouseCode, WarehouseId FROM dbo.Tw_MaterialStock WHERE ISNULL(WarehouseCode, '') <> '' AND ISNULL(WarehouseId, '') = ''; /* 仓库重名检查:如果同一项目有重名仓库,历史名称数据无法唯一回填,需要先处理重名。 */ SELECT ProjectId, WarehouseName, COUNT(1) AS RepeatCount FROM dbo.Base_Warehouse GROUP BY ProjectId, WarehouseName HAVING COUNT(1) > 1;