Trigger not preforming as expected overwriting all records instead of last inserted record.

My appologies if this is the wrong location for this, Mods, please feel free to relocate this post as appropriatewe have a SQL 2008 trigger that is not preforming as expected.instead of updating the package table by shipmentnumber summing the WEIGHT, FRIEGHTOVERIDE and FREIGHTCOST with common shpmentnumber from our UPS package table.

Our sys admin implemented this code into production before it was fully tested and approved for use and is now having to restore the package table as it has the same value for all records in the weight freightoverride and freightcost of the last id that was inserted into the table. I need to get this back on track and  resolve the original issue if possible. Any assistance would be appreciated.


[quote]

USE [e32TestCompany]
GO
/****** Object: Trigger [dbo].[UPSPackage_Package_I_TR] Script Date: 07/23/2015 15:33:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[UPSPackage_Package_I_TR]

ON [dbo].[UPSPackage]
FOR INSERT
AS

BEGIN
DECLARE @LastID INT = NULL

UPDATE Package
SET Package.TrackingNumber = Inserted.TrackingNumber,
Package.WEIGHT = CONVERT(REAL, Inserted.WEIGHT),
Package.ShipMethod = Inserted.ShipMethod,

Package.FreightOverrideAmount = (SELECT CASE WHEN Shipment.ThirdPartyBilling = '' AND LEFT(OrderHeader.OutsideOrderID,2) NOT IN ('IC','AF','RB','CM','DA') AND Package.PackageID = CONVERT(INT,Inserted.ShipmentNumber) THEN CONVERT(MONEY, Inserted.FreightOverrideAmount)
WHEN Shipment.ThirdPartyBilling = '' AND LEFT(OrderHeader.OutsideOrderID,2) IN ('IC','AF','RB','CM','DA') AND Package.PackageID = CONVERT(INT,Inserted.ShipmentNumber) THEN Package.FreightOverrideAmount ELSE 0 END
FROM Package
INNER JOIN Shipment ON Package.ShipmentNumber = Shipment.ShipmentNumber AND Package.PackageID = CONVERT(INT, Inserted.ShipmentNumber)
INNER JOIN OrderHeader ON Package.JobNumber = OrderHeader.JobNumber),

Package.FreightCost = CONVERT(MONEY, Inserted.FreightCost),
Package.ShipDate = CONVERT(DATETIME, Inserted.UPSDatetime),@LastID = CONVERT(INT, Inserted.ShipmentNumber)
FROM Package, Inserted

WHERE Package.PackageID = CONVERT(INT, Inserted.ShipmentNumber)



MERGE dbo.Package AS pkg
USING (SELECT ShipmentNumber, SUM(Cast (Weight as float)) Weight, SUM(Cast (FreightCost as float)) FreightCost, SUM(Cast (FreightOverrideAmount as float)) FreightOverrideAmount
FROM dbo.UPSPackage where ShipmentNumber = @LastID
GROUP BY ShipmentNumber) as ups1 ON ups1.ShipmentNumber = @LastID
When MATCHED THEN UPDATE SET Weight =ups1.Weight,FreightCost = ups1.FreightCost,FreightOverrideAmount = ups1.FreightOverrideAmount
When NOT MATCHED THEN INSERT (ShipmentNumber,Weight,FreightCost,FreightOverrideAmount) VALUES(ups1.ShipmentNumber, ups1.weight,ups1.FreightCost,ups1.FreightOverrideAmount);



END
[/quote]

.

July 24th, 2015 8:26pm

so the UPSpackage table has many duplicate shipment numbers on unique records that have each tracking number for that shipments weioght, freight cost, and the freight cost override. The package table has only unique shipment numbers that the trigger writes the weight freight cost and freight cost override to.

It was discovered that it was not written to SUM all records with the same shipment numbers and combine them into a single record in the package table and that instead an employee was manually correcting this. The project was assigned and delegated to rewrite the trigger to include the sum of each of those fields as part of writing the single unique record of the shipment number.

I've been here a month or two and have barely gotten together a basic project management plan together because of issues like this where they have fired off projects without allowing full testing (yes I am about to pull out my hair, my experience and use is limited with SQL to about 5 years ago and while I can follow along and spot issues they tend to be a little trigger happy leaving me to solve issues like this one)

Here is the UPS Package table sample data

ID	ShipMethod	JobNumber	Weight	TrackingNumber	ShipDate	FreightCost	PackageID	UPSDatetime	FreightOverrideAmount
161089	FEDEX	89231	13.8	3080969942	NULL	116.51	598501	2/25/2015	547.69
161097	FEDEX	89231	35	3080970082	NULL	142.69	598502	2/25/2015	670.74
161098	FEDEX	89231	28	3080971515	NULL	141.64	598503	2/25/2015	616.71
161099	FEDEX	89231	4	3080971644	NULL	107.97	598501	2/25/2015	502.79
161100	FEDEX	89231	12	3080971751	NULL	141.64	598505	2/25/2015	616.71
161101	FEDEX	89231	2.5	3080971913	NULL	107.97	598502	2/25/2015	415.42
161102	FEDEX	89231	1.4	3080972075	NULL	164.94	598510	2/25/2015	775.34
161103	FEDEX	89231	12.5	3080972204	NULL	107.97	598501	2/25/2015	422.49
161104	FEDEX	89231	4.3	3080972252	NULL	141.64	611627	2/25/2015	633.95
161106	FEDEX	89231	7	3080972440	NULL	141.64	598502	2/25/2015	594.22
161107	FEDEX	89231	8	3080972591	NULL	107.97	598520	2/25/2015	422.49
161108	FEDEX	89231	9.7	3080972672	NULL	107.97	611627	2/25/2015	428.63
161109	FEDEX	89231	6	3080972775	NULL	141.64	598501	2/25/2015	578.11
161110	FEDEX	89231	1.4	3080973022	NULL	141.64	598529	2/25/2015	638.7
161111	FEDEX	89231	4.4	3080973221	NULL	141.64	598534	2/25/2015	578.11
161114	FEDEX	89231	1.4	3080973280	NULL	111.61	611627	2/25/2015	524.64
161115	FEDEX	89231	2.7	3080973420	NULL	141.64	598501	2/25/2015	578.11
161116	FEDEX	89231	9.4	3080973534	NULL	108.44	598538	2/25/2015	509.76
161117	FEDEX	89231	6	3080973604	NULL	107.97	598539	2/25/2015	333.89
158749	FEDEX	cwo#2216 benjamin ma	1	3080402323	NULL	361.93	611627	2/11/2015	1704.6
158653	FEDEX	90854	2.9	3080318780	NULL	108.79	611783	2/9/2015	512.37
160986	FEDEX	91944	3.4	3080917674	NULL	100.78	611627	2/24/2015	313.7
161031	FEDEX	88756	2.75	3080944834	NULL	107.8	611627	2/24/2015	307.77
158911	FEDEX	15715&15718	13.6	3080541170	NULL	113.53	598501	2/13/2015	534.71



and here is the same data after it has been correctly updated in the package table.

ID	ShipMethod	JobNumber	Weight	TrackingNumber	ShipDate	FreightCost	ShipmentNumber	UPSDatetime	FreightOverrideAmount
158911	FEDEX	15715&15718	52.6	3080541170	NULL	729.26	598501	2/13/2015	3163.9
161106	FEDEX	89231	44.5	3080972440	NULL	392.3	598502	2/25/2015	1680.38
161098	FEDEX	89231	28	3080971515	NULL	141.64	598503	2/25/2015	616.71
161100	FEDEX	89231	12	3080971751	NULL	141.64	598505	2/25/2015	616.71
161102	FEDEX	89231	1.4	3080972075	NULL	164.94	598510	2/25/2015	775.34
161107	FEDEX	89231	8	3080972591	NULL	107.97	598520	2/25/2015	422.49
161110	FEDEX	89231	1.4	3080973022	NULL	141.64	598529	2/25/2015	638.7
161111	FEDEX	89231	4.4	3080973221	NULL	141.64	598534	2/25/2015	578.11
161116	FEDEX	89231	9.4	3080973534	NULL	108.44	598538	2/25/2015	509.76
161117	FEDEX	89231	6	3080973604	NULL	107.97	598539	2/25/2015	333.89
161031	FEDEX	88756	22.55	3080944834	NULL	931.73	611627	2/24/2015	3913.29
158653	FEDEX	90854	2.9	3080318780	NULL	108.79	611783	2/9/2015	512.37

and here is the code again better formated

USE [e32TestCompany]
GO
/****** Object: Trigger [dbo].[UPSPackage_Package_I_TR] Script Date: 07/23/2015 15:33:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[UPSPackage_Package_I_TR]

ON [dbo].[UPSPackage]
FOR INSERT
AS

BEGIN
DECLARE @LastID INT = NULL

UPDATE Package
SET Package.TrackingNumber = Inserted.TrackingNumber,
Package.WEIGHT = CONVERT(REAL, Inserted.WEIGHT),
Package.ShipMethod = Inserted.ShipMethod,

Package.FreightOverrideAmount = (SELECT CASE WHEN Shipment.ThirdPartyBilling = '' AND LEFT(OrderHeader.OutsideOrderID,2) NOT IN ('IC','AF','RB','CM','DA') AND Package.PackageID = CONVERT(INT,Inserted.ShipmentNumber) THEN CONVERT(MONEY, Inserted.FreightOverrideAmount)
WHEN Shipment.ThirdPartyBilling = '' AND LEFT(OrderHeader.OutsideOrderID,2) IN ('IC','AF','RB','CM','DA') AND Package.PackageID = CONVERT(INT,Inserted.ShipmentNumber) THEN Package.FreightOverrideAmount ELSE 0 END
FROM Package
INNER JOIN Shipment ON Package.ShipmentNumber = Shipment.ShipmentNumber AND Package.PackageID = CONVERT(INT, Inserted.ShipmentNumber)
INNER JOIN OrderHeader ON Package.JobNumber = OrderHeader.JobNumber),

Package.FreightCost = CONVERT(MONEY, Inserted.FreightCost),
Package.ShipDate = CONVERT(DATETIME, Inserted.UPSDatetime),@LastID = CONVERT(INT, Inserted.ShipmentNumber)
FROM Package, Inserted

WHERE Package.PackageID = CONVERT(INT, Inserted.ShipmentNumber)



MERGE dbo.Package AS pkg
USING (SELECT ShipmentNumber, SUM(Cast (Weight as float)) Weight, SUM(Cast (FreightCost as float)) FreightCost, SUM(Cast (FreightOverrideAmount as float)) FreightOverrideAmount
FROM dbo.UPSPackage where ShipmentNumber = @LastID
GROUP BY ShipmentNumber) as ups1 ON ups1.ShipmentNumber = @LastID
When MATCHED THEN UPDATE SET Weight =ups1.Weight,FreightCost = ups1.FreightCost,FreightOverrideAmount = ups1.FreightOverrideAmount
When NOT MATCHED THEN INSERT (ShipmentNumber,Weight,FreightCost,FreightOverrideAmount) VALUES(ups1.ShipmentNumber, ups1.weight,ups1.FreightCost,ups1.FreightOverrideAmount);

I asked the same questions that you did Earland and then came in this morning to find that they implemented this mess before I could review test and sign off on it....




  • Edited by luke102280 Friday, July 24, 2015 11:02 PM Shipmentnumber is called packageid in the ups package table
Free Windows Admin Tool Kit Click here and download it now
July 24th, 2015 10:58pm

Below is a version of the trigger reformatted to my liking. The reformatting reveals several funny things.

For instance, in the MERGE statement, we either insert a sum or update an existing row with the sum. My naïve asumption would be that the existing sum should be incremented. But I don't know anything of the business rules, or how the tables are related.

You posted some sample data, but it only serves to increase my confusion. The trigger makes it clear that the UPSPackage has a column called ShipmentNumber, but that column is not present in the sample data. But the sample data from Package includes a column with this name.

But a key question: For a given PackageID in Package, how many rows with this ShipmentNumber can there be in UPSPackage? If the answer is > 1, the UPDATE statement is even worse than we thought originally.

Also, what is this convert business, all over the trigger? What are the actual types of the columns?

In any case, I think your best strategy is to scrap this trigger and start over.

ALTER TRIGGER [dbo].[UPSPackage_Package_I_TR] ON [dbo].[UPSPackage]
FOR INSERT AS

BEGIN
DECLARE @LastID INT = NULL

UPDATE Package
SET    TrackingNumber = I.TrackingNumber,
       WEIGHT         = CONVERT(REAL, I.WEIGHT),
       ShipMethod     = I.ShipMethod,
       FreightOverrideAmount =
           (SELECT CASE WHEN S.ThirdPartyBilling = '' AND
                             LEFT(OH.OutsideOrderID,2) NOT IN ('IC','AF','RB','CM','DA') AND
                             P2.PackageID = CONVERT(INT, I.ShipmentNumber)
                           THEN CONVERT(MONEY, I.FreightOverrideAmount)
                        WHEN S.ThirdPartyBilling = '' AND LEFT(OH.OutsideOrderID,2) IN ('IC','AF','RB','CM','DA') AND Package.PackageID = CONVERT(INT,Inserted.ShipmentNumber)
                           THEN P2.FreightOverrideAmount
                        ELSE 0
                   END
            FROM   Package P2
            JOIN   Shipment S ON P2.ShipmentNumber = S.ShipmentNumber
            JOIN   OrderHeader ON ON Package.JobNumber = OH.JobNumber
            WHERE  P2.PackageID = CONVERT(INT, I.ShipmentNumber)),
       FreightCost = CONVERT(MONEY, I.FreightCost),
       ShipDate    = CONVERT(DATETIME, I.UPSDatetime),
       @LastID     = CONVERT(INT, I.ShipmentNumber)
FROM   Package P
JOIN   inserted I ON P.PackageID = CONVERT(INT, I.ShipmentNumber)

MERGE dbo.Package AS pkg
USING (SELECT ShipmentNumber,
              SUM(Cast (Weight AS float)) AS Weight,
              SUM(Cast (FreightCost AS float)) AS FreightCost,
              SUM(Cast (FreightOverrideAmount AS float)) FreightOverrideAmount
       FROM   dbo.UPSPackage
       WHERE  ShipmentNumber = @LastID
       GROUP BY ShipmentNumber) as ups1 ON ups1.ShipmentNumber = @LastID
WHEN  MATCHED THEN
      UPDATE
      SET     Weight      = ups.Weight,
              FreightCost = ups1.FreightCost,
              FreightOverrideAmount = ups1.FreightOverrideAmount
WHEN NOT MATCHED THEN
   INSERT (ShipmentNumber, Weight, FreightCost, FreightOverrideAmount)
      VALUES(ups1.ShipmentNumber, ups1.weight, ups1.FreightCost,
             ups1.FreightOverrideAmount)
;

July 25th, 2015 5:00am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics