SQL Server触发器,用于在插入之前将旧值与新值进行比较

时间:2016-05-05 09:21:15

标签: sql-server triggers

我在SQL Server中创建触发器时遇到问题,因为我不清楚如何使用旧值检查新值。

我有一个名为MTRL的主表和另一个名为CCCMTRL的表。我想在MTRL表上进行更新之前从MTRL表中选择MTRL列(MTRL表的主键),COMPANY和PRICE,并激活必须将MTRL的新价格与CCCMTRL的旧价格进行比较的触发器。 / p>

如果价格相同,则无需更新,但如果它们不同,则应在CCCMTRL中插入

INSERT INTO CCCMTRL(MTRL,COMPANY,OLDPRICE,NEWPRICE) 
VALUES (MTRL,COMPANY,OLD.PRICE,NEW.PRICE)
像这样的东西。

3 个答案:

答案 0 :(得分:0)

这可以使用INSTEAD OF INSERT TRIGGER来实现。

  1. 在表格

  2. 上创建视图
  3. 在视图顶部创建INSTEAD OF INSERT触发器。

    有关详情,请参阅以下网址

  4. https://technet.microsoft.com/en-us/library/ms175521%28v=sql.105%29.aspx

答案 1 :(得分:0)

我试图找出你为什么要经历处理触发器的麻烦。只需重新格式化您的插入物,以便它自动处理您的状况。

我必须假设CCCMTRL表中有一些额外字段,其中一个是价格日期变更,因为您没有提供价格总是增加或减少的条件,所以我&# 39; m 假设 这是由某种日期字段跟踪的,我在下面的示例查询中称之为DATEFIELD。

基本上,此查询将识别* new *价格是否不再与CCCMTRL表中的最新价格相匹配(排序由ROW_NUMBER()窗口函数执行)。如果您有任何不匹配,它们将被插入到CCCMTRL表中:

--Optionally insert DATEFIELD if this is not tracked via default constraint
INSERT INTO CCCMTRL(MTRL,COMPANY,OLDPRICE,NEWPRICE)
SELECT 
    t_window.MTRL, 
    t_window.COMPANY, 
    t_window.OLD_PRICE, 
    t_window.NEW_PRICE
FROM (
    SELECT 
        MTRL, 
        COMPANY, 
        OLD.PRICE AS OLD_PRICE, 
        NEW.PRICE AS NEW_PRICE, 
        ROW_NUMBER() (PARTITION BY OLD.MTRL, OLD.COMPANY ORDER BY OLD.DATEFIELD DESC) AS RowNum
    FROM CCCMTRL OLD LEFT OUTER JOIN CCCMTRL_NEW NEW
        ON  OLD.MTRL = NEW.MTRL
        AND OLD.COMPANY = NEW.COMPANY
    WHERE OLD.PRICE <> NEW.PRICE
) t_window
WHERE RowNum = 1

下面是一个快速示例查询,它有效地展示了我正在谈论的工作示例。希望这可以解决您的问题,而不会使触发器混乱您的数据库。

SELECT COL1, COL2, DT
FROM 
(
    SELECT COL1, COL2, DT, 
    -- Create Windows Based On Colums and Assign Number based on Age of records
    ROW_NUMBER() OVER (PARTITION BY COL1, COL2 ORDER BY DT DESC) AS RowNum
    FROM
    (
        -- Row will be filtered out as it's the oldest of Liquids/Blues
        SELECT 'Liquid' AS COL1, 'Blue' AS COL2, GETDATE() - 1 AS DT
        UNION
        SELECT 'Liquid', 'Blue', GETDATE()
        UNION
        SELECT 'Liquid', 'Red', GETDATE()
        UNION
        -- Row will be filtered out as it's the oldest of Solid/Greens
        SELECT 'Solid', 'Green', GETDATE()
        UNION
        SELECT 'Solid', 'Green', GETDATE() + 2
    ) t_example
) t_windowed
WHERE RowNum = 1

答案 2 :(得分:-1)

  

SQL Server触发器,用于在插入

之前将旧值与新值进行比较

不可能。 SQL Server 101,在文档中清晰可读:插入触发器之前没有。

你只有一个插入(插入后)和INSTEAD OF(这意味着没有插入,但你可以在检查后在触发器中插入)。

在你的情况下,后插入触发器也可以工作。