I’m working on a SQL Server stored procedure that inserts production data from multiple groups into a table. Each group produces one or more parts, and each part is associated with a unique PartId. The production data from each group is inserted into the DailyWeldingProduction table, and then into the DailyWeldingPaintProduction table.
However, I’m facing an issue when different groups produce the same part. This results in duplicate entries for the same PartId in the DailyWeldingPaintProduction table. Here’s a simplified version of my stored procedure:
CREATE TYPE dbo.PartAssemblyType AS TABLE
(
PartId INT,
Quantity INT,
UserId NVARCHAR(50),
CreationDate DATE,
Note NVARCHAR(50),
ShiftTimeId INT,
NextProcessId INT,
GroupId NVARCHAR(50)
);
CREATE TYPE dbo.EmployeeType AS TABLE
(
PartId INT,
Employee NVARCHAR(50),
GroupId NVARCHAR(50)
);
GO
ALTER PROCEDURE [dbo].[AddMetalFrameMarkDailyWeldingProduction]
@PartAssemblies dbo.PartAssemblyType READONLY,
@Employees dbo.EmployeeType READONLY
AS
BEGIN TRY
BEGIN TRANSACTION
-- Temporary table to store distinct groups with unique OrderNumbers
DECLARE @TempOrderNumbers TABLE (GroupId NVARCHAR(255), OrderNumber INT)
-- Generate unique OrderNumbers for each distinct GroupId
INSERT INTO @TempOrderNumbers (GroupId, OrderNumber)
SELECT DISTINCT GroupId, ROW_NUMBER() OVER (ORDER BY GroupId) + ISNULL(MAX(OrderNumber), 0)
FROM @PartAssemblies
CROSS JOIN (SELECT ISNULL(MAX(OrderNumber), 0) AS OrderNumber FROM [dbo].[WeldingEmployee]) AS maxOrder
GROUP BY GroupId
-- Declare a table variable to hold the IDs of the inserted rows
DECLARE @InsertedRows TABLE (Id INT, PartId INT)
-- Insert into DailyWeldingProduction with the generated OrderNumbers
INSERT INTO [dbo].[DailyWeldingProduction]
([FK_idPartShip], [Quantity], [UserID], [CreationDate], [SysDate], [Note], [FK_ShiftTime], [FK_idNextProcess], [OrderNumber])
OUTPUT INSERTED.Id, INSERTED.FK_idPartShip INTO @InsertedRows
SELECT pa.PartId, pa.Quantity, pa.UserId, pa.CreationDate, GETDATE(), pa.Note, pa.ShiftTimeId, pa.NextProcessId, t.OrderNumber
FROM @PartAssemblies pa
JOIN @TempOrderNumbers t ON pa.GroupId = t.GroupId
-- Insert into DailyWeldingPaintProduction
INSERT INTO [dbo].[DailyWeldingPaintProduction]
([FK_idPartShip], [Quantity], [UserID], [CreationDate], [SysDate], [Note], [FK_ShiftTime], [FK_idNextProcess], [IdDailyWeldingProduction])
SELECT ir.PartId, SUM(pa.Quantity), pa.UserId, pa.CreationDate, GETDATE(), pa.Note, pa.ShiftTimeId, 13, ir.Id
FROM @PartAssemblies pa
JOIN @InsertedRows ir ON pa.PartId = ir.PartId
WHERE pa.NextProcessId = 12
GROUP BY ir.PartId,pa.PartId, pa.UserId, pa.CreationDate, pa.Note, pa.ShiftTimeId, ir.Id;
-- Insert into WeldingEmployee with the generated OrderNumbers
INSERT INTO [dbo].[WeldingEmployee]
([FK_Employee], [CreationDate], [FK_ShiftTime], [FK_idPartShip], [OrderNumber])
SELECT e.Employee, p.CreationDate, p.ShiftTimeId, e.PartId, t.OrderNumber
FROM @Employees e
JOIN @PartAssemblies p ON e.PartId = p.PartId AND e.GroupId = p.GroupId
JOIN @TempOrderNumbers t ON e.GroupId = t.GroupId
-- Insert into DailyPaintProduction for Galvanisé
INSERT INTO [dbo].[DailyPaintProduction]
([FK_idPartShip], [Quantity], [UserID], [CreationDate], [SysDate], [Note], [FK_ShiftTime], [FK_idNextProcess])
SELECT pa.PartId, pa.Quantity, pa.UserId, pa.CreationDate, GETDATE(),
CASE
WHEN pi.FKGalva = 3 THEN 'Galvanisé'
WHEN pi.FKNoir = 4 THEN 'Produits Noir'
END,
pa.ShiftTimeId,
13
FROM @PartAssemblies pa
INNER JOIN [ProjectShipping] ps ON pa.PartId = ps.id
INNER JOIN [ProjectInfo] pi ON ps.IdProject = pi.id
WHERE (pi.FKGalva = 3 OR pi.FKNoir = 4) AND pa.NextProcessId = 12
UPDATE ps
SET
[WeldQty] = [WeldQty] + p.SumQuantity,
[WeldingPaintQty] = [WeldingPaintQty] + p.SumQuantity,
[PaintQty] = CASE
WHEN pi.FKNoir = 4 OR pi.FKGalva = 3 THEN [PaintQty] + p.SumQuantity
ELSE [PaintQty]
END
FROM [dbo].[ProjectShipping] ps
INNER JOIN
(
SELECT PartId, SUM(Quantity) AS SumQuantity
FROM @PartAssemblies
WHERE NextProcessId = 12
GROUP BY PartId
) p ON ps.id = p.PartId
LEFT JOIN [ProjectInfo] pi ON ps.IdProject = pi.id;
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
GO
For example, if Group 1 produces Part 1 with Quantity 3 and Group 2 produces Part 1 with Quantity 2, the DailyWeldingPaintProduction table ends up with duplicate entries for Part 1.
like this
PartId=1 Quantity=3
PartId=1 Quantity=2
PartId=1 Quantity=3
PartId=1 Quantity=2
I tried to add GroupId to @InsertedRows to differentiate between the groups, but then I get the error “The multi-part identifier ‘pa.GroupId’ could not be bound” in OUTPUT INSERTED.Id, INSERTED.FK_idPartShip, pa.GroupId INTO @InsertedRows.
How can I modify my stored procedure to avoid these duplicate entries in the DailyWeldingPaintProduction table, while still maintaining the link back to the DailyWeldingProduction table? Any help would be appreciated. Thanks! ????