Sql server 我能把这个触发器缩短/更好/更快吗?

Sql server 我能把这个触发器缩短/更好/更快吗?,sql-server,Sql Server,这项任务本身是非常基本的。我有一个交易表,可以将一定数量的产品移入或移出库存。要知道一个产品可以由多个“基础”产品组成,并且只有基础产品可能存在库存,这变得有点困难 我当前的触发器工作原理如下: 创建可以组合插入、删除和合成产品的临时表 将插入的非合成产品添加到此临时表 添加插入的组合产品 减去已删除的非合成产品 减去已删除的合成产品 我现在有一个包含所有非组合产品事务的表。但也就是说,一行更新后,同一产品会添加两次。一次减去旧值,一次添加新值 为联接的非组合产品创建第二个临时表 取产品的总和,

这项任务本身是非常基本的。我有一个交易表,可以将一定数量的产品移入或移出库存。要知道一个产品可以由多个“基础”产品组成,并且只有基础产品可能存在库存,这变得有点困难

我当前的触发器工作原理如下:

  • 创建可以组合插入、删除和合成产品的临时表
  • 将插入的非合成产品添加到此临时表
  • 添加插入的组合产品
  • 减去已删除的非合成产品
  • 减去已删除的合成产品
  • 我现在有一个包含所有非组合产品事务的表。但也就是说,一行更新后,同一产品会添加两次。一次减去旧值,一次添加新值

  • 为联接的非组合产品创建第二个临时表
  • 取产品的总和,并将其放入新的临时表中
  • 将股票与此临时表合并
  • 再一次。。我的触发器工作正常,我的性能没有问题,但我觉得我错过了一些东西。我打赌这附近一定有人有比我更好的解决方案

    我的表和示例数据:()

    我的触发器:

    ALTER TRIGGER [dbo].[StockCalculate]
    ON [dbo].[Transaction]
    AFTER INSERT, UPDATE, DELETE AS 
    
    BEGIN
        -- Create temporary table
        CREATE TABLE #TransactionsComposed (
            [load] [bit] NOT NULL,
            [plantId] [int] NOT NULL,
            [productId] [int] NOT NULL,
            [quantity] [float] NOT NULL
        );
    
        -- Insert basic materials
        INSERT INTO #TransactionsComposed (
            [load], [plantId], [productId], [quantity])
        SELECT 
            [Inserted].[load], 
            [Inserted].[plantId],
            [Inserted].[productId],
            [Inserted].[quantity]
        FROM 
            [Inserted]
            INNER JOIN [Product] ON [Product].[id] = [Inserted].[productId]
        WHERE 
            [Product].[composed] = 0;
    
        -- Insert operations
        INSERT INTO #TransactionsComposed (
            [load], [plantId], [productId], [quantity])
        SELECT 
            [Inserted].[load], 
            [Inserted].[plantId], 
            [ProductComposition].[productId], 
            ([Inserted].[quantity] * [ProductComposition].[quantity])
        FROM 
            [Inserted]
            INNER JOIN [Product] ON [Product].[id] = [Inserted].[productId]
            INNER JOIN [ProductComposition] ON [ProductComposition].[parentId] = [Product].[id]
        WHERE 
            [Product].[composed] = 1;
    
        -- Insert basic materials but ALTER it's load status.
        INSERT INTO #TransactionsComposed (
            [load], [plantId], [productId], [quantity])
        SELECT 
            CASE [Deleted].[load] 
                WHEN 0 THEN 1 
                WHEN 1 THEN 0 
            END,
            [Deleted].[plantId], 
            [Deleted].[productId],
            [Deleted].[quantity]
        FROM 
            [Deleted]
            INNER JOIN [Product] ON [Product].[id] = [Deleted].[productId]
        WHERE 
            [Product].[composed] = 0;
    
        -- Insert operations but ALTER it's load status.
        INSERT INTO #TransactionsComposed (
            [load], [plantId], [productId], [quantity])
        SELECT 
            CASE [Deleted].[load] 
                WHEN 0 THEN 1 
                WHEN 1 THEN 0 
            END,
            [Deleted].[plantId], 
            [ProductComposition].[productId], 
            ([Deleted].[quantity] * [ProductComposition].[quantity])
        FROM 
            [Deleted]
            INNER JOIN [Product] ON [Product].[id] = [Deleted].[productId]
            INNER JOIN [ProductComposition] ON [ProductComposition].[parentId] = [Product].[id]
        WHERE 
            [Product].[composed] = 1;
    
    
        -- Prepare multiple products for merge
        CREATE TABLE #TransactionsJoined (
            [plantId] [int] NOT NULL,
            [productId] [int] NOT NULL,
            [quantity] [float] NOT NULL
        );
    
        INSERT INTO #TransactionsJoined
            ([plantId], [productId], [quantity])
        SELECT
            [plantId],
            [productId],
            SUM(CASE [load]
                    WHEN 0 THEN [quantity]
                    WHEN 1 THEN 0 - [quantity]
                END)
        FROM
            #TransactionsComposed
        GROUP BY [plantId], [productId]
    
    
        -- Merge composed transactions into the stock
        MERGE [Stock]
        USING #TransactionsJoined
        ON [Stock].[plantId]=#TransactionsJoined.[plantId]
        AND [Stock].[productId]=#TransactionsJoined.[productId]
        WHEN NOT MATCHED BY TARGET THEN 
            INSERT ([plantId], [productId], [quantity]) 
            VALUES (
                #TransactionsJoined.[plantId], 
                #TransactionsJoined.[productId], 
                #TransactionsJoined.[quantity])
        WHEN MATCHED THEN 
            UPDATE SET
                [Stock].[quantity] = [Stock].[quantity] + #TransactionsJoined.[quantity],
                [Stock].[dateUpdate] = GETDATE();
    END
    

    你也许可以。然而,读取示例数据并不容易(尽管您为其发布了DDL+DML,这很好!),而且您想要的结果也不太清楚。请考虑编辑你的问题(如果你需要任何人的帮助,不要叫我们“聪明人”)让它更清楚。这并不意味着侮辱;我尽量使问题简短明了。使用示例数据,您可以添加一个事务,结果将显示在Stock表中。有关于如何澄清的提示吗?
    ALTER TRIGGER [dbo].[StockCalculate]
    ON [dbo].[Transaction]
    AFTER INSERT, UPDATE, DELETE AS 
    
    BEGIN
        -- Create temporary table
        CREATE TABLE #TransactionsComposed (
            [load] [bit] NOT NULL,
            [plantId] [int] NOT NULL,
            [productId] [int] NOT NULL,
            [quantity] [float] NOT NULL
        );
    
        -- Insert basic materials
        INSERT INTO #TransactionsComposed (
            [load], [plantId], [productId], [quantity])
        SELECT 
            [Inserted].[load], 
            [Inserted].[plantId],
            [Inserted].[productId],
            [Inserted].[quantity]
        FROM 
            [Inserted]
            INNER JOIN [Product] ON [Product].[id] = [Inserted].[productId]
        WHERE 
            [Product].[composed] = 0;
    
        -- Insert operations
        INSERT INTO #TransactionsComposed (
            [load], [plantId], [productId], [quantity])
        SELECT 
            [Inserted].[load], 
            [Inserted].[plantId], 
            [ProductComposition].[productId], 
            ([Inserted].[quantity] * [ProductComposition].[quantity])
        FROM 
            [Inserted]
            INNER JOIN [Product] ON [Product].[id] = [Inserted].[productId]
            INNER JOIN [ProductComposition] ON [ProductComposition].[parentId] = [Product].[id]
        WHERE 
            [Product].[composed] = 1;
    
        -- Insert basic materials but ALTER it's load status.
        INSERT INTO #TransactionsComposed (
            [load], [plantId], [productId], [quantity])
        SELECT 
            CASE [Deleted].[load] 
                WHEN 0 THEN 1 
                WHEN 1 THEN 0 
            END,
            [Deleted].[plantId], 
            [Deleted].[productId],
            [Deleted].[quantity]
        FROM 
            [Deleted]
            INNER JOIN [Product] ON [Product].[id] = [Deleted].[productId]
        WHERE 
            [Product].[composed] = 0;
    
        -- Insert operations but ALTER it's load status.
        INSERT INTO #TransactionsComposed (
            [load], [plantId], [productId], [quantity])
        SELECT 
            CASE [Deleted].[load] 
                WHEN 0 THEN 1 
                WHEN 1 THEN 0 
            END,
            [Deleted].[plantId], 
            [ProductComposition].[productId], 
            ([Deleted].[quantity] * [ProductComposition].[quantity])
        FROM 
            [Deleted]
            INNER JOIN [Product] ON [Product].[id] = [Deleted].[productId]
            INNER JOIN [ProductComposition] ON [ProductComposition].[parentId] = [Product].[id]
        WHERE 
            [Product].[composed] = 1;
    
    
        -- Prepare multiple products for merge
        CREATE TABLE #TransactionsJoined (
            [plantId] [int] NOT NULL,
            [productId] [int] NOT NULL,
            [quantity] [float] NOT NULL
        );
    
        INSERT INTO #TransactionsJoined
            ([plantId], [productId], [quantity])
        SELECT
            [plantId],
            [productId],
            SUM(CASE [load]
                    WHEN 0 THEN [quantity]
                    WHEN 1 THEN 0 - [quantity]
                END)
        FROM
            #TransactionsComposed
        GROUP BY [plantId], [productId]
    
    
        -- Merge composed transactions into the stock
        MERGE [Stock]
        USING #TransactionsJoined
        ON [Stock].[plantId]=#TransactionsJoined.[plantId]
        AND [Stock].[productId]=#TransactionsJoined.[productId]
        WHEN NOT MATCHED BY TARGET THEN 
            INSERT ([plantId], [productId], [quantity]) 
            VALUES (
                #TransactionsJoined.[plantId], 
                #TransactionsJoined.[productId], 
                #TransactionsJoined.[quantity])
        WHEN MATCHED THEN 
            UPDATE SET
                [Stock].[quantity] = [Stock].[quantity] + #TransactionsJoined.[quantity],
                [Stock].[dateUpdate] = GETDATE();
    END