2016-06-28 4 views
1

Ich habe diese Tabellenstruktur:Massenaktualisierung der gleichen Zeile Spalte Trigger in SQL Server mit

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

Diese Tabelle mit 1000 Datensätze mit DaysCount als Nullwert gefüllt wird.

Ich habe einen Trigger erstellt, wie unten für diese Tabelle zu aktualisieren DaysCount. Immer wenn es ein Update von DateOfJoining oder Status Spalten gibt, sollte DaysCount im Trigger berechnet werden und automatisch aktualisiert werden.

Dies ist der Umriss des Abzugs:

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 

Ich bin in der Lage die Zählung immer aktualisiert einzelnen Datensatz zu sehen. Bei Bulk-Updates wird nur der erste Datensatz aktualisiert.

Mit Hilfe von stackoverflow habe ich versucht, anstelle von Trigger, TRIGGER_NESTLEVEL(), etc. Optionen zu verwenden, aber immer noch alle anderen Rest der Zeilen nicht aktualisiert.

Schnellere Hilfe geschätzt.

Antwort

0

ich dies in zwei getrennte Auslöser aufzuteilen würde empfehlen - eine für INSERT, eine für UPDATE. Erleichtert die Arbeit mit dem Code.

auch: Ihre Trigger wird einmal pro Anweisung aufgerufen werden - nicht einmal pro Zeile - so können Sie einen Wert aus der Inserted Pseudo-Tabelle wie folgt nicht nur aus (da diese Pseudo-Tabelle neu enthalten alle 25 eingefügte Zeilen - nicht nur eine):

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

Welche der 25 eingefügten Reihen würden Sie betrachten ?? Es ist willkürlich und unbestimmt - und Sie werden nur bei eine Reihe betrachten und ignorieren alle anderen 24 Reihen .....

So ist die INSERT Auslöser sollte wie folgt aussehen:

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 

Da Sie keine vorherigen Werte, es muss nicht überprüft werden, ob eine dieser beiden Spalten aktualisiert wurde.

Ihre UPDATE Trigger sollte wie folgt aussehen:

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 
+0

Hallo Marc, Mein scenario ist die unten Abfrage ausführen (idealerweise sollte es alle Datensätze aktualisieren) und wiederum alle Zeilen der Spalte DaysCount sollte basierend auf diesem Zeilenwert aktualisiert werden. Aber jetzt, wenn ich die obige Abfrage ausführen, aktualisiert es den ersten Datensatz allein UPDATE JoiningDate SET STATUS = 'Verbunden' –

+0

Der Trigger aktualisiert * nur * die Zeilen, die tatsächlich aktualisiert wurden. Wie viele Zeilen hat Ihre 'UPDATE'-Anweisung beeinflusst? –

+0

für 1000 Zeilen, für obige Update-Anweisung, es sagt 1000 Zeilen betroffen sind. aber tatsächlich, erste Reihe allein wurde aktualisiert für Spalte DaysCount andere Zeilen sind immer noch NULL –

0

Nur ein Datensatz wird aktualisiert, da nur ein Datensatz aktualisiert wird, auch wenn es sich um einen Massensatz handelt.

Auch Sie sollten sagen, wie Ihre genaue Formel aussieht.

Sie sollten Ihren Code dies ändern:

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 @[email protected]+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 
+0

Dies ist ** NICHT ** gehen im Fall eines 'INSERT' arbeiten, da Sie die' @ Flg' auf 1 gesetzt, aber nie zu 2, und du führst die 'UPDATE'-Anweisung ** nur ** aus, wenn' @Flg = 2 '(was bei einem INSERT nicht der Fall ist) ...... was versuchst du mit dieser '@Flg zu erreichen 'wie auch immer ??? –

+0

Hauptkriterium ist, dass, wenn bestimmte Spalte aktualisiert werden, nur Update-Anweisung sollte feuern.So Flag Logik ist nicht erforderlich, trotzdem ich hv korrigiert meine Flag-Logik zu.so wenn Flag = 1 bedeutet, eingefügt, wenn Flag-2 bedeutet nur löschen und wenn Flag = 3 bedeutet das aktualisiert. – KumarHarsh

+0

'UPDATE JoiningDate SET STATUS = 'Joined'' Aber wenn ich die obige Abfrage wie pro Trigger ausführen, sollte es DaysCount für alle 1000 Zeilen aktualisieren, aber es aktualisiert den ersten Datensatz allein –