Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

SQL Server 2012 Update-Trigger

Frage Entwicklung Datenbanken

Mitglied: EUuser

EUuser (Level 1) - Jetzt verbinden

21.02.2014 um 13:41 Uhr, 3500 Aufrufe, 7 Kommentare, 2 Danke

Hallo zusammen,

ich habe eine Frage zu einem Update-Trigger im SQL Server 2012:

Ich habe einen Trigger, der bei einem Update eines Datensatzes automatisch die Attribute modified und modifiedby füllen sollte:

01.
USE [Database] 
02.
GO 
03.
 
04.
CREATE TRIGGER [dbo].[Modified] ON [dbo].Tabelle 
05.
AFTER UPDATE 
06.
AS  
07.
BEGIN 
08.
SET NOCOUNT ON; 
09.
UPDATE dbo.Tabelle  
10.
SET dbo.Tabelle.modified = now, dbo.Tabelle.modifiedby = SUSER_SNAME() 
11.
FROM dbo.Tabelle 
12.
JOIN inserted 
13.
ON dbo.Tabelle.key = inserted.key 
14.
END
Leider bekomme ich immer die Fehlermeldung:
Meldung 156, Ebene 15, Status 1, Prozedur Modified, Zeile 11
Falsche Syntax in der Nähe des key-Schlüsselworts.

Ich komme einfach nicht dahinter, wo der Fehler liegt...

Es wäre schön, wenn jmd hier mir helfen könnte!

Vielen Dank schon einmal und schöne Grüße!
Felix
Mitglied: Biber
21.02.2014, aktualisiert um 14:14 Uhr
Moin EUuser,

könnte ja ganz banal das fehlende Semikolon sein...

Aber:
  • Warum ein AFTER INSERT-Trigger (statt BEFORE INSERT) und drängender noch

  • warum keine Füllung der Felder durch einen DEFAULT-Wert?

Die Felder können doch durchaus NOT NULL deklariert werden, wenn sie ohnehin immer gefüllt werden.
Und auch SUSER_SNAME kann als DEFAULT-Einschränkung in ALTER TABLE oder CREATE TABLE verwendet werden.

  • Warum ein Join auf die Tabelle "inserted"???? Wogegen soll das denn helfen?

  • Was treibt dich, ohne Not bei deinen Tabellen/Feldern Namen wie "inserted", "modified" oder "key" zu verwenden.
Also reservierte Worte oder Worte mit hoher Kollisionsgefahr in jedem SQL-Dialekt - und absolut nicht eindeutig.
Hasardeur? Oder sonst zu wenig Nervenkitzel zu Hause?

Grüße
Biber
Bitte warten ..
Mitglied: EUuser
21.02.2014, aktualisiert um 15:53 Uhr
Zitat von Biber:

Moin EUuser,

könnte ja ganz banal das fehlende Semikolon sein...

Aber:
  • Warum ein AFTER INSERT-Trigger (statt BEFORE INSERT) und drängender noch

  • warum keine Füllung der Felder durch einen DEFAULT-Wert?

Die Felder können doch durchaus NOT NULL deklariert werden, wenn sie ohnehin immer gefüllt werden.
Und auch SUSER_SNAME kann als DEFAULT-Einschränkung in ALTER TABLE oder CREATE TABLE verwendet werden.

  • Warum ein Join auf die Tabelle "inserted"???? Wogegen soll das denn helfen?

  • Was treibt dich, ohne Not bei deinen Tabellen/Feldern Namen wie "inserted", "modified" oder "key"
zu verwenden.
Also reservierte Worte oder Worte mit hoher Kollisionsgefahr in jedem SQL-Dialekt - und absolut nicht eindeutig.
Hasardeur? Oder sonst zu wenig Nervenkitzel zu Hause?

Grüße
Biber

Hi Biber,

ich hab das mal so gelernt
ich möchte ja nur am gerade geupdateten Datensatz die Attribute"modified" und "modifiedby" füllen.

Falls du einen Tipp für einen besseren Weg kennst, dann immer her damit.

VG
Felix



EDIT:
Okay... hab es mit default werten gelöst
Bitte warten ..
Mitglied: EUuser
21.02.2014 um 15:56 Uhr
Zitat von Biber:

Moin EUuser,

könnte ja ganz banal das fehlende Semikolon sein...

Aber:
  • Warum ein AFTER INSERT-Trigger (statt BEFORE INSERT) und drängender noch

  • warum keine Füllung der Felder durch einen DEFAULT-Wert?

Die Felder können doch durchaus NOT NULL deklariert werden, wenn sie ohnehin immer gefüllt werden.
Und auch SUSER_SNAME kann als DEFAULT-Einschränkung in ALTER TABLE oder CREATE TABLE verwendet werden.

  • Warum ein Join auf die Tabelle "inserted"???? Wogegen soll das denn helfen?

  • Was treibt dich, ohne Not bei deinen Tabellen/Feldern Namen wie "inserted", "modified" oder "key"
zu verwenden.
Also reservierte Worte oder Worte mit hoher Kollisionsgefahr in jedem SQL-Dialekt - und absolut nicht eindeutig.
Hasardeur? Oder sonst zu wenig Nervenkitzel zu Hause?

Grüße
Biber


Okay, verstanden

Jetzt die große Frage: Wie mach ich das am besten, wenn ich einen Trigger für ganz neue Tupel, sprich ein created und createdby -Attribut füllen möchte?
Das darf ja nicht bei jedem Updatevorgang überschrieben werden


VG und Danke
Felix
Bitte warten ..
Mitglied: Biber
21.02.2014 um 17:03 Uhr
Moin EUuser,

sorry, ich hatte auch überlesen, dass es um einen UPDATE-Trigger ging. Mein Fehler.

Also: je nach Anforderung der "Updateprotokollierung" sehe ich zwei Möglichkeiten:
a) es so das Ereignis "Satz neu angelegt von user am Datum" automatisch mit erfasst werden und das Datum des letzten Updates und der ändernde User
b) es soll eine komplette Historie im Hintergrund erzeugt werden mit alle jemals vorhandenden Datensatzzuständen, also auch dem Ereignis "Satz wurde gelöscht" sowie Löschdatum+löschender User

Fall a) geht ja innerhalb dieser einen Tabellen - mit
  • 2 Feldern für CreatedTS, CreatedBy (per Default gefüllt)
  • 2 Feldern für ModifiedTS, ModifiedBy (per BEFORE UPDATE-Trigger gefüllt, Felder nicht sichtbar für den User und nicht gesetzt per etwaigem Update-Statement)

Fall b) ist aufwendiger - der geht ja nur mit einer Clone-Tabelle (=alle Felder der Originaltabelle), und zusätzlich die Felder:
  • ValidFromTS und ValidToTS gehören für den Gültig-Von/Gültig-Bis-Zeitraum des aktiven Satzes
  • ein Feld für die UserID created/modified (modifiedBy)
  • ein Feld für die UserID (deletedBy)

Dann brauchst du allerdings auf der Originaltabelle 3 Trigger:
- einen After Insert-Trigger auf der Originaltabelle
-> legt eine Kopie des gerade angelegten Originalsatzes in der Hist-Tabelle an mit ValidFrom =now() und ValidTo = unendlich /31.12.9999 und der UserId ins Feld "modifiedBy"
- einen After Update-Trigger auf der Originaltabelle
-> ändert den Historiesatz, der "unendlich" gültig war auf "ValidToTS = now() minus 1 Sekunde und legt eine Kopie des gerade angelegten Originalsatzes in der Hist-Tabelle an mit ValidFrom =now() und ValidTo = unendlich /31.12.9999 und der UserId ins Feld "modifiedBy"

- einen After Delete-Trigger auf der Originaltabelle
-> ändert den Historiesatz, der "unendlich" gültig war auf "ValidToTS = now() minus 1 Sekunde und setzt das Feld deletedBy


Grüße
Biber
Bitte warten ..
Mitglied: MadMax
24.02.2014 um 13:20 Uhr
Hallo Felix,

mal abgesehen von den ganzen Sachen, die Biber Dir da noch versucht beizubringen, liegt Dein Problem an den Namen Deiner Spalten und könnte Dich also auch an anderer Stelle in Schwierigkeiten bringen. "key" ist ein Schlüsselwort in SQL Server und kann so nicht verwendet werden. Mal abgesehen davon, daß man solche Schlüsselworte als Spalten- oder sonstige Objektnamen meiden sollte, könnte man sie auch in eckige Klammern packen und dann trotzdem verwenden. [key] geht also, key geht nicht. Aber wie gesagt: besser ist, man vermeidet das gänzlich.

Gruß, Mad Max
Bitte warten ..
Mitglied: EUuser
27.02.2014 um 13:45 Uhr
Zitat von Biber:

Moin EUuser,

sorry, ich hatte auch überlesen, dass es um einen UPDATE-Trigger ging. Mein Fehler.

Also: je nach Anforderung der "Updateprotokollierung" sehe ich zwei Möglichkeiten:
a) es so das Ereignis "Satz neu angelegt von user am Datum" automatisch mit erfasst werden und das Datum des letzten
Updates und der ändernde User
b) es soll eine komplette Historie im Hintergrund erzeugt werden mit alle jemals vorhandenden Datensatzzuständen, also auch
dem Ereignis "Satz wurde gelöscht" sowie Löschdatum+löschender User

Fall a) geht ja innerhalb dieser einen Tabellen - mit
  • 2 Feldern für CreatedTS, CreatedBy (per Default gefüllt)
  • 2 Feldern für ModifiedTS, ModifiedBy (per BEFORE UPDATE-Trigger gefüllt, Felder nicht sichtbar für den User und
nicht gesetzt per etwaigem Update-Statement)

Fall b) ist aufwendiger - der geht ja nur mit einer Clone-Tabelle (=alle Felder der Originaltabelle), und zusätzlich die
Felder:
  • ValidFromTS und ValidToTS gehören für den Gültig-Von/Gültig-Bis-Zeitraum des aktiven Satzes
  • ein Feld für die UserID created/modified (modifiedBy)
  • ein Feld für die UserID (deletedBy)

Dann brauchst du allerdings auf der Originaltabelle 3 Trigger:
- einen After Insert-Trigger auf der Originaltabelle
-> legt eine Kopie des gerade angelegten Originalsatzes in der Hist-Tabelle an mit ValidFrom =now() und ValidTo = unendlich
/31.12.9999 und der UserId ins Feld "modifiedBy"
- einen After Update-Trigger auf der Originaltabelle
-> ändert den Historiesatz, der "unendlich" gültig war auf "ValidToTS = now() minus 1 Sekunde und
legt eine Kopie des gerade angelegten Originalsatzes in der Hist-Tabelle an mit ValidFrom =now() und ValidTo = unendlich
/31.12.9999 und der UserId ins Feld "modifiedBy"

- einen After Delete-Trigger auf der Originaltabelle
-> ändert den Historiesatz, der "unendlich" gültig war auf "ValidToTS = now() minus 1 Sekunde und
setzt das Feld deletedBy


Grüße
Biber

Hi Biber,

genau Fall a möchte ich abbilden.
Wie bekomme ich es denn hin, dass ich nur in dem gerade geänderten Datensatz per Trigger die Attribute ModifiedTS und ModifiedBy füllen lasse.
Meine Trigger überschreiben dann alle Datensätze, was ja nicht ganz der Sinn der Sache ist... ;)
Ich nutze für ModifiedTS GetDate() und für ModifiedBy System_User.
Bitte warten ..
Mitglied: EUuser
27.02.2014 um 16:08 Uhr
So liebe Leute,
nach etwas rumprobieren fiel es mir wie Schuppen aus den Haaren:

01.
USE [Database] 
02.
GO 
03.
 
04.
CREATE TRIGGER [dbo].[Modified] ON [dbo].Tabelle 
05.
AFTER INSERT, UPDATE 
06.
AS  
07.
BEGIN 
08.
SET NOCOUNT ON; 
09.
UPDATE dbo.Tabelle  
10.
SET dbo.Tabelle.ModifiedTS = GetDate(), dbo.Tabelle.ModifiedBy = SYSTEM_USER 
11.
FROM dbo.Tabelle 
12.
JOIN inserted 
13.
ON dbo.Tabelle.Primärschlüssel = inserted.Primärschlüssel 
14.
END
Danke für eure Hilfe und Denkanstöße!

VG
Felix
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(1)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Heiß diskutierte Inhalte
LAN, WAN, Wireless
gelöst Server erkennt Client nicht wenn er ausserhalb des DHCP Pools liegt (28)

Frage von Mar-west zum Thema LAN, WAN, Wireless ...

Outlook & Mail
Outlook 2010 findet ost datei nicht (18)

Frage von Floh21 zum Thema Outlook & Mail ...

Windows Server
Server 2008R2 startet nicht mehr (Bad Patch 0xa) (18)

Frage von Haures zum Thema Windows Server ...