Frage

Ich habe einen Trigger gebaut, wo ich Prioritäten zu halten, um versuchen und erlaubt keine doppelten Prioritätswerten. Es gibt einige Dinge zu beachten.

  1. Der Benutzer kann die Priorität freier Form in.
  2. Es gibt nichts, um sie von der Kommissionierung die gleiche Priorität wie ein anderes Element zu blockieren.
  3. Wenn ein Wert auf einem anderen Wert gleich das neu priorisierten Objekt hat Vorrang in der eingetragene Priorität ist, soll und der andere soll erhöht werden.

    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
    

Ich habe nicht diesen Trigger eine ganze Menge getestet, so, wenn es Bereiche, die frei fühlen zu sprechen. Was ich will schließlich wissen, ob ich versuchen sollte, und wandeln diese zu einem einzigen Update mit einer Case-Anweisung. (Wenn das auch möglich.)

Wenn es würde mehr performant sein, diese eine einzige UPDATE Aussage zu machen ich wirklich eine Hand Bezifferung es verwenden könnte aus!

War es hilfreich?

Lösung

Sie müssen die Trigger neu zu schreiben. Er geht davon aus nur einem Datensätze jemals an atime eingefügt / aktualisiert oder delted werden. Sie können keinen Trigger mit dieser Annahme schreiben, arbeiten Trigger auf Chargen von Daten nicht zeilen byrow. Sie müssen eingefügt verbinden und in Ihren Updates gelöscht. Also ja, ich würde versuchen, das Update mit einer Case-Anweisung zu schreiben.

Und warum ist dies ein gelöschtes Trigger? Dort gewann;. T arecord zu aktualisieren, wenn es gelöscht wurde

Andere Tipps

Stellen Sie sicher, dass Sie ein Rollback und heben einen Fehler (Schweregrad 16), wenn @@ ROWCOUNT> 1. Ihr Trigger geschrieben, wie sie derzeit eine große Menge an Daten Korruption des Benutzers verursachen würde versucht, einfügen, aktualisieren oder mehrere Zeilen auf einmal löschen.

Das heißt, IronGoofy richtig ist: Sie wird nur einmal auf den Tisch berühren, unabhängig davon, ob die Bedingung. Also, es heraus in mehrere Anweisungen zu brechen macht den Code leichter zu lesen / mehr wartbar.

Wenn Sie mehr Zeilen zu ermöglichen, waren auf einmal aktualisiert werden, würden Sie brauchen, um dies zu ändern. Die Logik kann entmutigend sein!

Wie wäre es damit:

 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

Es sollte kein (spürbar) Unterschied in der Leistung sein, in jedem Fall werden Sie eine einzelne Update-Anweisung an die Datenbank herausgeben.

ich beschlossen, diese Idee zu Graben, und ich überlasse es dem UI, um die Priorität zu aktualisieren. Ich habe aufgehört, eine Benutzereingabe zu ermöglichen.

Ich bin nicht sicher, welche dieser Antworten richtig sind, so werde ich dies als richtig markieren und die Gemeinschaft Figur es aus mit Versuch und Irrtum lassen. :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top