0

「購入日」と「保証期限」を含む列を持つコンピューターのテーブルがあります。各コンピューター (行) の「購入日」の日付値に 4 年を追加し、その結果を「保証期限」列に入れたいと思います。また、可能であれば、新しいコンピューターを作成して購入日を入力すると、これが自動的に行われるようにしたいと考えています。

ありがとう

4

1 に答える 1

6

列をドロップして、計算済みにします。

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。行を書き込み、ログに影響を与え、おそらくページ分割を引き起こし、次に行を削除し、ログに影響を与え、後でクリーンアップする必要があるゴースト行を追加する代わりに、単純に救済して挿入をまったく実行しません。

于 2013-10-25T14:39:53.543 に答える