1

私はこのテーブル構造を持っています:

CREATE TABLE JoiningDate 
(
    Id INT,
    DateofJoining DATETIME,
    STATUS VARCHAR(10),
    DaysCount INT
)

このテーブルには、DaysCount が NULL 値の 1000 レコードが含まれています。

このテーブルを更新するために、以下のようにトリガーを作成しましたDaysCountDateOfJoiningまたはStatus列の更新があるたびにDaysCount、トリガーで計算され、自動的に更新されます。

トリガーの概要は次のとおりです。

CREATE TRIGGER [dbo].[trigger_JoiningDate] 
ON [dbo].[JoiningDate]
AFTER INSERT, UPDATE
AS
BEGIN
    DECLARE @Id INT
    DECLARE @DateJoining DATETIME
    DECLARE @Result INT

    SELECT @Id = Id,
           @DateJoining = DateofJoining, 
    FROM INSERTED   

    SET @Result = [Formula To Calculate Days]

    UPDATE JoiningDate 
    SET DaysCount = @Result  
    WHERE Id = @Id
END

単一のレコードのカウントが更新されているのを確認できます。ただし、一括更新の場合、最初のレコードのみが更新されます。

stackoverflow の助けを借りて、トリガー、TRIGGER_NESTLEVEL() などのオプションの代わりに使用しようとしましたが、他のすべての行は更新されません。

より迅速なヘルプに感謝します。

4

2 に答える 2

1

これを2 つの別個のトリガーに分割することをお勧めします。1 つは 用INSERT、もう 1 つは 用UPDATEです。コードの操作がはるかに簡単になります。

また、トリガーはステートメントごとに1回呼び出されます-行ごとに1回ではありませInsertedん-したがって、このような疑似テーブルから値を選択することはできません(疑似テーブルには、 1つだけではなく、新しく挿入された25行すべてが含まれるため):

SELECT 
    @Id = Id,
    @DateJoining = DateofJoining, 
FROM INSERTED   

挿入された 25 行のうち、どれを見ますか?? それは恣意的で未定です-さらに、 1行だけを見て、他の24行をすべて無視します.....

したがって、INSERTトリガーは次のようになります。

CREATE TRIGGER [dbo].[trigger_JoiningDate_Insert] 
ON [dbo].[JoiningDate]
AFTER INSERT
AS
BEGIN
    UPDATE jd
    SET DaysCount = [Formula To Calculate Days]
    FROM JoiningDate jd
    INNER JOIN Inserted i ON i.Id = jd.Id
END

以前の値がないため、これら 2 つの列のいずれかが更新されたかどうかを確認する必要はありません。

トリガーUPDATEは次のようになります。

CREATE TRIGGER [dbo].[trigger_JoiningDate_Update] 
ON [dbo].[JoiningDate]
AFTER UPDATE
AS
BEGIN
    UPDATE jd
    SET DaysCount = DATEDIFF(DAY, jd.DateofJoining, SYSDATETIME())
    FROM JoiningDate jd
    INNER JOIN Inserted i ON i.Id = jd.Id
    INNER JOIN Deleted d ON d.Id = i.Id
    -- check whether "DateOfJoining" or "Status" have been updated
    WHERE
        i.DateOfJoining <> d.DateOfJoining 
        OR i.Status <> d.Status 
END
于 2016-06-28T06:58:16.920 に答える
0

一括レコードの場合でも 1 つのレコードのみを更新しているため、1 つのレコードのみが更新されます。

また、正確な式がどのように見えるかを伝える必要があります。

コードを次のように変更する必要があります。

DECLARE @Id INT
  DECLARE @DateJoining DATETIME
  DECLARE @Result INT

    Declare @Flg int=0
    --if exists(select top 1 id from inserted)
    --set @Flg=1
    --if exists(select top 1 id from deleted)
    --set @Flg=@Flg+2
    if (COLUMNS_UPDATED(DateJoining) or COLUMNS_UPDATED([status]))
    begin

  SET @Result = [Formula To Calculate Days]
  --what is the actual formula ?
  UPDATE jd SET DaysCount = @Result  
        FROM INSERTED i
        inner join JoiningDate jd on i.id=jd.id  
end
于 2016-06-28T04:40:34.030 に答える