diff --git a/svc/queries/orderproduction_items.go b/svc/queries/orderproduction_items.go index b42dfe3..63ff05c 100644 --- a/svc/queries/orderproduction_items.go +++ b/svc/queries/orderproduction_items.go @@ -787,6 +787,7 @@ func ValidateProductionBarcodePlan(q sqlQueryRower, variants []models.OrderProdu func InsertItemBarcodesTx(tx *sql.Tx, orderHeaderID string, lines []models.OrderProductionUpdateLine, username string) (int64, error) { start := time.Now() + if len(lines) == 0 { log.Printf("[InsertItemBarcodesTx] lines=0 inserted=0 duration_ms=0") return 0, nil @@ -794,6 +795,7 @@ func InsertItemBarcodesTx(tx *sql.Tx, orderHeaderID string, lines []models.Order lineIDs := make([]string, 0, len(lines)) seen := make(map[string]struct{}, len(lines)) + for _, line := range lines { lineID := strings.TrimSpace(line.OrderLineID) if lineID == "" { @@ -805,8 +807,9 @@ func InsertItemBarcodesTx(tx *sql.Tx, orderHeaderID string, lines []models.Order seen[lineID] = struct{}{} lineIDs = append(lineIDs, lineID) } + if len(lineIDs) == 0 { - log.Printf("[InsertItemBarcodesTx] lines=%d uniqueLineIDs=0 inserted=0 duration_ms=%d", len(lines), time.Since(start).Milliseconds()) + log.Printf("[InsertItemBarcodesTx] uniqueLineIDs=0 inserted=0") return 0, nil } @@ -814,15 +817,19 @@ func InsertItemBarcodesTx(tx *sql.Tx, orderHeaderID string, lines []models.Order var inserted int64 for i := 0; i < len(lineIDs); i += chunkSize { + end := i + chunkSize if end > len(lineIDs) { end = len(lineIDs) } + chunk := lineIDs[i:end] values := make([]string, 0, len(chunk)) args := make([]any, 0, len(chunk)+2) + paramPos := 1 + for _, lineID := range chunk { values = append(values, fmt.Sprintf("(@p%d)", paramPos)) args = append(args, lineID) @@ -831,52 +838,61 @@ func InsertItemBarcodesTx(tx *sql.Tx, orderHeaderID string, lines []models.Order orderHeaderParam := paramPos usernameParam := paramPos + 1 + args = append(args, orderHeaderID, username) query := fmt.Sprintf(` -SET NOCOUNT ON; -;WITH srcLine (OrderLineID) AS ( +SET NOCOUNT ON +; + +WITH srcLine (OrderLineID) AS ( SELECT * - FROM (VALUES %s) AS v (OrderLineID) + FROM (VALUES %s) v(OrderLineID) ), + src AS ( SELECT DISTINCT l.ItemTypeCode, - UPPER(LTRIM(RTRIM(ISNULL(l.ItemCode, '')))) AS ItemCode, - UPPER(LTRIM(RTRIM(ISNULL(l.ColorCode, '')))) AS ColorCode, - UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim1Code, '')))) AS ItemDim1Code, - UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim2Code, '')))) AS ItemDim2Code, - CAST('' AS NVARCHAR(50)) AS ItemDim3Code - FROM dbo.trOrderLine l WITH (UPDLOCK, HOLDLOCK) + UPPER(LTRIM(RTRIM(ISNULL(l.ItemCode,'')))) ItemCode, + UPPER(LTRIM(RTRIM(ISNULL(l.ColorCode,'')))) ColorCode, + UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim1Code,'')))) ItemDim1Code, + UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim2Code,'')))) ItemDim2Code, + CAST('' AS NVARCHAR(50)) ItemDim3Code + FROM dbo.trOrderLine l JOIN srcLine s - ON CAST(l.OrderLineID AS NVARCHAR(50)) = s.OrderLineID + ON CAST(l.OrderLineID AS NVARCHAR(50)) = s.OrderLineID WHERE l.OrderHeaderID = @p%d - AND NULLIF(LTRIM(RTRIM(ISNULL(l.ItemCode, ''))), '') IS NOT NULL + AND NULLIF(LTRIM(RTRIM(ISNULL(l.ItemCode,''))), '') IS NOT NULL ), + missing AS ( SELECT - s.ItemTypeCode, - s.ItemCode, - s.ColorCode, - s.ItemDim1Code, - s.ItemDim2Code, - s.ItemDim3Code, + s.*, ROW_NUMBER() OVER ( - ORDER BY s.ItemCode, s.ColorCode, s.ItemDim1Code, s.ItemDim2Code, s.ItemDim3Code - ) AS RowNo + ORDER BY + s.ItemCode, + s.ColorCode, + s.ItemDim1Code, + s.ItemDim2Code, + s.ItemDim3Code + ) RowNo FROM src s - LEFT JOIN dbo.prItemBarcode b WITH (UPDLOCK, HOLDLOCK) - ON b.BarcodeTypeCode = 'BAGGI3' - AND b.UnitOfMeasureCode = 'AD' - AND b.ItemTypeCode = s.ItemTypeCode - AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemCode, '')))) = s.ItemCode - AND UPPER(LTRIM(RTRIM(ISNULL(b.ColorCode, '')))) = s.ColorCode - AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim1Code, '')))) = s.ItemDim1Code - AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim2Code, '')))) = s.ItemDim2Code - AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim3Code, '')))) = s.ItemDim3Code - WHERE b.Barcode IS NULL + WHERE NOT EXISTS ( + SELECT 1 + FROM dbo.prItemBarcode b + WHERE b.BarcodeTypeCode = 'BAGGI3' + AND b.UnitOfMeasureCode = 'AD' + AND b.ItemTypeCode = s.ItemTypeCode + AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemCode,'')))) = s.ItemCode + AND UPPER(LTRIM(RTRIM(ISNULL(b.ColorCode,'')))) = s.ColorCode + AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim1Code,'')))) = s.ItemDim1Code + AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim2Code,'')))) = s.ItemDim2Code + AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim3Code,'')))) = s.ItemDim3Code + ) ) -INSERT INTO dbo.prItemBarcode ( + +INSERT INTO dbo.prItemBarcode +( Barcode, BarcodeTypeCode, ItemTypeCode, @@ -893,8 +909,9 @@ INSERT INTO dbo.prItemBarcode ( LastUpdatedDate, RowGuid ) + SELECT - CAST(seed.MaxBarcode + m.RowNo AS NVARCHAR(50)) AS Barcode, + CAST(seed.MaxBarcode + m.RowNo AS NVARCHAR(50)), 'BAGGI3', m.ItemTypeCode, m.ItemCode, @@ -909,29 +926,46 @@ SELECT @p%d, GETDATE(), NEWID() -FROM missing m -CROSS JOIN ( - SELECT ISNULL(MAX(TRY_CONVERT(BIGINT, NULLIF(LTRIM(RTRIM(Barcode)), ''))), 0) AS MaxBarcode - FROM dbo.prItemBarcode WITH (UPDLOCK, HOLDLOCK) - WHERE TRY_CONVERT(BIGINT, NULLIF(LTRIM(RTRIM(Barcode)), '')) IS NOT NULL -) seed; -SELECT @@ROWCOUNT AS Inserted; +FROM missing m + +CROSS JOIN ( + SELECT ISNULL(MAX(TRY_CONVERT(BIGINT, Barcode)),0) MaxBarcode + FROM dbo.prItemBarcode +) seed `, strings.Join(values, ","), orderHeaderParam, usernameParam, usernameParam) chunkStart := time.Now() - var chunkInserted int64 - if err := tx.QueryRow(query, args...).Scan(&chunkInserted); err != nil { - log.Printf("[InsertItemBarcodesTx] ERROR orderHeaderID=%s chunk=%d-%d err=%v", orderHeaderID, i, end, err) - return inserted, fmt.Errorf("upsert item barcodes chunk failed chunkStart=%d chunkEnd=%d duration_ms=%d: %w", i, end, time.Since(chunkStart).Milliseconds(), err) + + res, err := tx.Exec(query, args...) + + if err != nil { + log.Printf("[InsertItemBarcodesTx] ERROR chunk=%d-%d err=%v", i, end, err) + return inserted, err } - inserted += chunkInserted - log.Printf("[InsertItemBarcodesTx] orderHeaderID=%s chunk=%d-%d chunkInserted=%d cumulative=%d duration_ms=%d", - orderHeaderID, i, end, chunkInserted, inserted, time.Since(chunkStart).Milliseconds()) + + rows, _ := res.RowsAffected() + + inserted += rows + + log.Printf( + "[InsertItemBarcodesTx] chunk=%d-%d inserted=%d cumulative=%d duration_ms=%d", + i, + end, + rows, + inserted, + time.Since(chunkStart).Milliseconds(), + ) } - log.Printf("[InsertItemBarcodesTx] orderHeaderID=%s lines=%d uniqueLineIDs=%d inserted=%d duration_ms=%d", - orderHeaderID, len(lines), len(lineIDs), inserted, time.Since(start).Milliseconds()) + log.Printf( + "[InsertItemBarcodesTx] lines=%d unique=%d inserted=%d duration_ms=%d", + len(lines), + len(lineIDs), + inserted, + time.Since(start).Milliseconds(), + ) + return inserted, nil } @@ -964,11 +998,7 @@ func UpsertItemAttributesTx(tx *sql.Tx, attrs []models.OrderProductionItemAttrib args = append(args, username) query := fmt.Sprintf(` -SET NOCOUNT ON; -DECLARE @updated INT = 0; -DECLARE @inserted INT = 0; - -;WITH src (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode) AS ( +WITH src (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode) AS ( SELECT * FROM (VALUES %s) AS v (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode) ) @@ -982,9 +1012,8 @@ JOIN src ON src.ItemTypeCode = tgt.ItemTypeCode AND src.ItemCode = tgt.ItemCode AND src.AttributeTypeCode = tgt.AttributeTypeCode; -SET @updated = @@ROWCOUNT; -;WITH src (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode) AS ( +WITH src (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode) AS ( SELECT * FROM (VALUES %s) AS v (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode) ) @@ -1015,17 +1044,15 @@ LEFT JOIN dbo.prItemAttribute tgt AND src.ItemCode = tgt.ItemCode AND src.AttributeTypeCode = tgt.AttributeTypeCode WHERE tgt.ItemCode IS NULL; -SET @inserted = @@ROWCOUNT; - -SELECT (@updated + @inserted) AS Affected; `, strings.Join(values, ","), usernameParam, strings.Join(values, ","), usernameParam, usernameParam) - var chunkAffected int64 chunkStart := time.Now() - if err := tx.QueryRow(query, args...).Scan(&chunkAffected); err != nil { + res, err := tx.Exec(query, args...) + if err != nil { log.Printf("[UpsertItemAttributesTx] ERROR chunk=%d-%d err=%v", i, end, err) return affected, fmt.Errorf("upsert item attributes chunk failed chunkStart=%d chunkEnd=%d duration_ms=%d: %w", i, end, time.Since(chunkStart).Milliseconds(), err) } + chunkAffected, _ := res.RowsAffected() affected += chunkAffected log.Printf("[UpsertItemAttributesTx] chunk=%d-%d chunkAffected=%d cumulative=%d duration_ms=%d", i, end, chunkAffected, affected, time.Since(chunkStart).Milliseconds())