「購入日」と「保証期限」を含む列を持つコンピューターのテーブルがあります。各コンピューター (行) の「購入日」の日付値に 4 年を追加し、その結果を「保証期限」列に入れたいと思います。また、可能であれば、新しいコンピューターを作成して購入日を入力すると、これが自動的に行われるようにしたいと考えています。
ありがとう
「購入日」と「保証期限」を含む列を持つコンピューターのテーブルがあります。各コンピューター (行) の「購入日」の日付値に 4 年を追加し、その結果を「保証期限」列に入れたいと思います。また、可能であれば、新しいコンピューターを作成して購入日を入力すると、これが自動的に行われるようにしたいと考えています。
ありがとう
列をドロップして、計算済みにします。
ALTER TABLE dbo.TableName DROP COLUMN WarrantyExpires;
ALTER TABLE dbo.TableName ADD WarrantyExpires
AS CONVERT(DATE, DATEADD(YEAR, 4, DatePurchased));
または、さらに良いことに、これを保存しないでください。すべての行で同じであるため (4 年以外の保証がない場合)、実行時に計算を実行するだけです。
すべての行で同じでない場合、または顧客が (現在または後で) 保証を延長できる場合、計算列は適していません。その代わり:
ALTER TABLE dbo.TableName ADD WarrantyExpires DATE;
次に、INSTEAD OF
挿入によって提供される値 (上書きするために使用する) または購入日から 4 年 (有効期限の値が指定されていない場合) に応じて、おそらくそれを入力するトリガー。そう:
CREATE TRIGGER dbo.FixWarrantyDate
ON dbo.TableName
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.TableName(OrderID, /* other cols, */ DatePurchased, WarrantyExpires)
SELECT OrderID, /* other cols, */ COALESCE(DatePurchased,GETDATE()),
COALESCE(WarrantyExpires,DATEADD(YEAR,4,COALESCE(DatePurchased,GETDATE())))
FROM inserted;
END
GO
したがって、デフォルトのケースでは、ベースインサートは次のようになります。
INSERT dbo.TableName(OrderID, DatePurchased, WarrantyExpires)
SELECT 1, GETDATE(), NULL;
-- or
INSERT dbo.TableName(OrderID, DatePurchased)
SELECT 2, GETDATE();
-- or even:
INSERT dbo.TableName(OrderID) SELECT 3;
また、誰かが延長保証を購入した場合は、それを無効にする (または後で手動で更新する) ことができます。
INSERT dbo.TableName(OrderID, DatePurchased, WarrantyExpires)
SELECT 4, GETDATE(), DATEADD(YEAR, 5, GETDATE());
これらの 4 つの挿入後の表の結果データ:
OrderID DatePurchased WarrantyExpires
------- ------------- ---------------
1 2013-10-25 2017-10-25
2 2013-10-25 2017-10-25
3 2013-10-25 2017-10-25
4 2013-10-25 2018-10-25
INSTEAD OF
ここで、トリガーを好む理由についても説明する必要があると感じています。挿入ステートメントを書き直す必要がありますが、after トリガーでは必要ありませんが、次の利点があります。
ビジネス ロジックを処理した後でも、1 つのステートメントで挿入 (および after トリガーが通常処理する更新) を実行できます。これは、ログにとって非常に使いやすいです。
トランザクションをロールバックする可能性のあるトリガーにビジネス ロジックがある場合は、トリガーでこれを行う方がはるかに優れていますINSTEAD OF
。行を書き込み、ログに影響を与え、おそらくページ分割を引き起こし、次に行を削除し、ログに影響を与え、後でクリーンアップする必要があるゴースト行を追加する代わりに、単純に救済して挿入をまったく実行しません。