it-swarm.com.de

Wie füge ich in einer SQL Server-Tabelle eine Spalte "zuletzt geändert" und "erstellt" hinzu?

Ich entwerfe ein neues Datenbankschema für eine SQL Server 2012-Datenbank.

Jede Tabelle sollte zwei zusätzliche Spalten namens modified und created enthalten, die automatisch geändert werden sollten, sobald eine Zeile eingefügt oder aktualisiert wird.

Ich weiß nicht, wie der beste Weg dahin ist.

Ich gehe davon aus, dass dieser Auslöser der beste Weg ist, damit umzugehen.

Ich habe versucht, Beispiele mit Triggern zu finden .. aber die Tutorials, die ich gefunden habe, fügen Daten in eine andere Tabelle ein usw. 

Ich nahm an, dass dies ein ziemlich gewöhnliches Szenario ist, aber ich konnte noch keine Antwort finden.

26
stevo

Die created-Spalte ist einfach - nur eine DATETIME2(3)-Spalte mit einer Standardeinschränkung, die gesetzt wird, wenn eine neue Zeile eingefügt wird:

Created DATETIME2(3) 
   CONSTRAINT DF_YourTable_Created DEFAULT (SYSDATETIME())

Wenn Sie also eine Zeile in YourTable einfügen und keinen Wert für Created angeben, wird der Wert auf das aktuelle Datum und die aktuelle Uhrzeit gesetzt.

Die Variable modified ist etwas mehr Arbeit, da Sie einen Trigger für den Fall AFTER UPDATE schreiben und aktualisieren müssen - Sie können SQL Server nicht deklarativ dazu auffordern, dies für Sie zu tun.

Modified DATETIME2(3)

und dann

CREATE TRIGGER updateModified
ON dbo.YourTable
AFTER UPDATE 
AS
   UPDATE dbo.YourTable
   SET modified = SYSDATETIME()
   FROM Inserted i
   WHERE dbo.YourTable.PrimaryKey = i.PrimaryKey

Sie müssen sich der Inserted-Pseudo-Tabelle anschließen, die alle Zeilen enthält, die mit Ihrer Basistabelle in Ihrem Primärschlüssel für diese Tabelle aktualisiert wurden.

Und Sie müssen diesen AFTER UPDATE-Auslöser für jede Tabelle erstellen, in der Sie eine modified-Spalte haben möchten.

34
marc_s

Im Allgemeinen können Sie die folgenden Spalten haben:

  • Zuletzt geändert durch
  • LastModifiedOn
  • Erstellt von
  • Erstellt am

dabei sind LastModifiedBy und CreatedBy Verweise auf eine users-Tabelle (UserID) und die Spalten LastModifiedOn und CreatetOn Datums- und Uhrzeitspalten.

Sie haben folgende Möglichkeiten:

  1. Lösung ohne Auslöser - Ich habe irgendwo gelesen, dass "Der beste Weg, Auslöser zu schreiben, ist, solche Auslöser nicht zu schreiben." Und Sie sollten wissen, dass sie normalerweise die Leistung beeinträchtigen. Wenn Sie sie vermeiden können, ist es besser, dies zu tun. In einigen Fällen kann es sogar am einfachsten sein, Trigger zu verwenden.

    Bearbeiten Sie einfach alle Ihre INSERT- und UPDATE-Anweisungen so, dass sie das aktuelle UserID und das aktuelle Datum und die aktuelle Uhrzeit enthalten. Wenn ein solcher user ID nicht definiert werden kann (anonymer Benutzer), können Sie stattdessen 0 verwenden. Der Standardwert der Spalten (falls kein user ID angegeben ist, ist NULL). Wenn Sie NULL-Werte sehen, sollten Sie die "schuldigen" Anweisungen finden und bearbeiten.

  2. Lösung mit Auslösern - Sie können AFTER INSERT, UPDATE auslösen und die Benutzerspalten dort ausfüllen. Es ist einfach, das aktuelle Datum und die aktuelle Uhrzeit im Kontext des Auslösers abzurufen (verwenden Sie beispielsweise GETUTCDATE()). Das Problem hierbei ist, dass die Trigger keine Parameter übergeben/annehmen dürfen. Da Sie den user ID-Wert nicht einfügen, können Sie ihn nicht an den Trigger übergeben. Wie finde ich den aktuellen Benutzer? 

    Sie können SET CONTEXT_INFO und CONTEXT_INFO verwenden. Vor allen insert- und update-Anweisungen müssen Sie den SET CONTEXT_INFO mit dem current user ID zum aktuellen Kontext hinzufügen und im Trigger die CONTEXT_INFO-Funktion verwenden, um ihn zu extrahieren.

Wenn Sie also Auslöser verwenden, müssen Sie erneut alle INSERT- und UPDATE-Klauseln bearbeiten. Aus diesem Grund ziehe ich es vor, sie nicht zu verwenden.

Wenn Sie nur Datums- und Zeitspalten benötigen und nicht von Spalten erstellt/geändert werden, ist die Verwendung von Triggern dauerhafter und einfacher, da Sie jetzt und in Zukunft keine anderen Anweisungen bearbeiten.


Mit SQL Server 2016 können wir jetzt die Funktion SESSION_CONTEXT verwenden, um Sitzungsdetails zu lesen. Die Details werden mit sp_set_session_context (als read-only oder read and write) festgelegt. Die Dinge sind ein bisschen benutzerfreundlich:

EXEC sp_set_session_context 'user_id', 4;  
SELECT SESSION_CONTEXT(N'user_id');  

Ein schönes Beispiel .

8
gotqn

Achtung, oben funktioniert gut, aber nicht in allen Fällen. Ich verlor viel Zeit und fand das hilfreich:

create TRIGGER yourtable_update_insert
ON yourtable
AFTER UPDATE 
as
begin
   set nocount on;
   update yourtable set modified=getdate(), modifiedby = suser_sname()
   from  yourtable t 
   inner join inserted i on t.uniqueid=i.uniqueid 
end
go

set nocount on; wird benötigt, ansonsten erhalten Sie den Fehler:


Microsoft SQL Server Management Studio


Es wurde keine Zeile aktualisiert.

Die Daten in Zeile 5 wurden nicht festgeschrieben . Fehlerquelle: Microsoft.SqlServer.Management.DataTools . Fehlermeldung: Die aktualisierten oder gelöschten Zeilenwerte machen entweder die Zeile nicht eindeutig oder ändern mehrere Zeilen (2 Reihen).

Korrigieren Sie die Fehler und versuchen Sie es erneut oder drücken Sie ESC, um die Änderung (en) abzubrechen. 


OK Hilfe 


1
pietervnk
CREATE TRIGGER [dbo].[updateModified]
   ON  [dbo].[Transaction_details] 
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
    UPDATE dbo.Transaction_details
    SET ModifedDate = GETDATE() FROM dbo.Transaction_details t JOIN inserted i ON 
    t.TransactionID = i.TransactionID--SYSDATETIME()
END
0
G.Protocol