質問

優先順位を適切に保ち、重複する優先順位値を許可しないようにするトリガーを作成しました。考慮すべきことがいくつかあります。

  1. ユーザーは優先度を自由に設定できます。
  2. 他のアイテムと同じ優先度を選択することを妨げるものは何もありません。
  3. 値が別の値と等しく入力された場合、新しく優先順位が付けられた項目が優先順位で優先され、もう一方が増分される必要があります。

    CREATE TRIGGER dbo.trg_Priority
        ON  dbo.Stories
        AFTER INSERT,UPDATE,DELETE
    AS
    BEGIN
        SET NOCOUNT ON;
    
    -- Insert statements for trigger here
    DECLARE @StoryId INT
    DECLARE @OldLocation INT
    DECLARE @NewLocation INT
    
    SELECT @NewLocation = Priority, @StoryId = StoryId FROM INSERTED
    SELECT @OldLocation = Priority FROM DELETED
    
    IF @NewLocation = @OldLocation
        RETURN;
    
    IF @NewLocation IS NULL
    BEGIN
        UPDATE Stories SET
            Priority = Priority - 1
        WHERE Priority > @OldLocation
    END
    
    IF @NewLocation > @OldLocation
    BEGIN
        UPDATE Stories SET
            Priority = Priority + 1
        WHERE Priority >= @NewLocation
        AND StoryId <> @StoryId
    END
    
    IF @NewLocation < @OldLocation
    BEGIN
        UPDATE Stories SET
            Priority = Priority + 1
        WHERE Priority >= @NewLocation
        AND Priority < @OldLocation
        AND StoryId <> @StoryId
    END
    END
    GO
    

このトリガーを十分にテストしていないので、懸念のある分野がある場合は、お気軽に声をかけてください。最終的に知りたいのは、これをcaseステートメントを使用して単一の更新に変換してみるべきかどうかです。 (それが可能であれば。)

これを単一の UPDATE ステートメントにするとパフォーマンスが向上する場合は、実際に手を使って考え出すことができます!

役に立ちましたか?

解決

トリガーを書き換える必要があります。一度に1つのレコードのみが挿入/更新または削除されることを想定しています。その前提でトリガーを記述することはできません。トリガーは行単位ではなくデータのバッチで動作します。更新で挿入および削除に参加する必要があります。はい、そうです、私はcaseステートメントで更新を書きます。

そして、なぜこれが削除されたトリガーなのですか?削除された場合、更新するレコードはありません。

他のヒント

@@ ROWCOUNT&gt;の場合、必ずロールバックしてエラー(重大度16)を発生させてください。 1.現在作成されているトリガーは、一度に複数の行を挿入、更新、または削除しようとしたユーザーの大量のデータ破損を引き起こします。

とはいえ、IronGoofyは正しいです。条件に関係なく、テーブルに触れるのは1回だけです。そのため、複数のステートメントに分割すると、コードが読みやすくなり、保守が容易になります。

複数の行を一度に更新できるようにする場合、これを変更する必要があります。ロジックは手ごわいかもしれません!

これについてはどうですか:

 UPDATE Stories SET Priority = CASE 
     WHEN Priority > @OldLocation THEN Priority-1
     WHEN Priority >= @NewLocation AND StoryID <> @StoryID THEN Priority+1
     WHEN Priority >= @NewLocation AND @Priority < @OldLocation And StoryID <> StoryID THEN Priority +1
END
GO

(顕著な)パフォーマンスの違いはありません。いずれの場合も、データベースに単一の更新ステートメントを発行します。

私はこのアイデアを捨てることにし、優先度を更新するためにUIに任せることにしました。ユーザー入力の許可を停止しました。

これらの回答のどれが正しいかわからないので、これを正しいとマークし、コミュニティに試行錯誤をさせます。 :)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top