2015-10-18 17 views
1

我在做練習測試之前,70-461的考試和問題之一是創建表:使列始終包含計算的值,而不觸發

  • 有4列,saleid,單價,數量,以及價格。
  • 價格通過單位價格和金額的乘積計算得出
  • 您不能使用觸發器。

最後一個殺了我。我怎麼能沒有觸發器呢?這裏是我的解決方案,而不是觸發器。

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 
+0

爲什麼不創建一個視圖? – jarlh

+1

因爲這是任務,要創建一個這樣的表=] – Skylerdw

回答

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

+0

@Skylerdw看到我更新的答案,特別是關於觸發器部分 – lad2025

+1

謝謝!這比我想象的要容易。 – Skylerdw

+0

@Skylerdw不客氣,考試好運。 – lad2025