0
votes

I have the following tables which join on idProduct = id (one to one):

Products

  • idProduct
  • description

ProductKeys

  • id
  • ProductKey

I need to create a trigger on the Products table for single and bulk inserts and updates which updates the key in ProductKeys for a product based on the product description.

If the product has a key, update the key to the description, else insert a new key.

The product key has to be unique per product.

So, if the key already exists for a different product, append the idProduct to the description to create the key.

My problem:

I have the trigger working for insert and update except for scenarios where there are 2 different products being inserted or updated with the same description. In this scenario, the key that's being generated is the same for both products.

Any ideas?

Here's my trigger using a MERGE statement:

CREATE TRIGGER [dbo].[UpdateKey]
ON  [dbo].[Products] 
AFTER  INSERT, UPDATE
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

        MERGE ProductKeys [Target]
        USING 
            (
                SELECT
                    CASE 
                        WHEN pk.id IS NULL 
                            THEN i.description
                        ELSE  
                            i.description + '_' + CAST(i.idProduct AS VARCHAR)
                        END [NewProductKey]
                    , i.idProduct
                FROM
                    INSERTED i
                    LEFT OUTER JOIN ProductKeys pk ON pk.id <> i.idProduct AND pk.ProductKey = i.description
                ) [source]
        ON (target.id = source.idproduct)
        WHEN NOT MATCHED THEN 
            INSERT
                ( 
                    id
                    , ProductKey
                )
            VALUES
                (
                        source.idProduct
                        , source.NewProductKey
                )
        WHEN MATCHED THEN
            UPDATE SET
                ProductKey = source.NewProductKey;
1

1 Answers

0
votes

I added a LEFT JOIN on INSERTED to check if duplicates are in the source. My source query now looks like:

SELECT
    CASE 
        WHEN pk.id IS NULL AND i2.idProduct IS NULL
            THEN i.description
        ELSE  
            i.description + '_' + CAST(i.idProduct AS VARCHAR)
        END [NewProductKey]
    , i.idProduct
FROM
    INSERTED i
    LEFT OUTER JOIN ProductKeys pk ON pk.id <> i.idProduct AND pk.ProductKey = i.description
    LEFT OUTER JOIN INSERTED i2 ON  i2.description = i.description AND i.idProduct <> i2.idProduct

This is works OK for me - when there are 2 products in the source with the same description, both will have its id appended to the key.

However if there's a way to have the key of the first product without the id - just the description - and have the rest with the id, that would be ideal.