使列始终包含没有触发器的计算值

时间:2015-10-18 14:20:23

标签: sql sql-server triggers

我在70-461考试前做过练习测试,其中一个问题就是创建表格:

  • 有4列,saleid,unitprice,金额和价格。
  • 价格按单位价格和金额的乘积计算
  • 您不能使用触发器。

最后一个杀了我。如何在没有触发器的情况下完成它?这是我使用而不是触发器的解决方案。

CREATE TABLE [HR].[Stuff](
    [saleid] [int] IDENTITY(1,1) NOT NULL,
    [unitprice] [float] NOT NULL,
    [amount] [float] NOT NULL,
    [price] [float] NULL,
)
GO

CREATE TRIGGER [calculate_price_insert]
ON [HR].[Stuff]
INSTEAD OF INSERT
AS
    DECLARE @unitprice float = (SELECT TOP 1 unitprice from inserted )
    DECLARE @amount float = (SELECT TOP 1 amount from inserted)
    INSERT INTO HR.[Stuff]
    VALUES(@unitprice,@amount, @unitprice*@amount)
GO

CREATE TRIGGER [calculate_price_update]
ON [HR].[Stuff]
INSTEAD OF UPDATE
AS
    DECLARE @unitprice float = (SELECT TOP 1 unitprice from inserted )
    DECLARE @amount float = (SELECT TOP 1 amount from inserted)
    UPDATE HR.[Stuff]
    SET unitprice = @unitprice, amount = @amount, price = @unitprice*@amount
    WHERE unitprice = (SELECT TOP 1 saleid from inserted)
GO

1 个答案:

答案 0 :(得分:2)

您需要使用计算列:

CREATE TABLE [HR].[Stuff](
    [saleid] [int] IDENTITY(1,1) NOT NULL,
    [unitprice] [float] NOT NULL,
    [amount] [float] NOT NULL,
    [price] AS ([unitprice] * [amount])
)

LiveDemo

同时将单位价格和金额存储为FLOAT可能会有危险,因为FLOAT不是准确的数据类型。请改用DECIMAL(12,4)

您的原始触发器解决方案将失败,因为触发器是按语句执行的,而不是每行执行。试试:

INSERT INTO [HR].[Stuff](unitprice, amount) VALUES (10, 20), (30, 50), (100,1);

您将使用INSERT丢失记录,并使用多个UPDATE获取错误结果。

SqlFiddleDemo