MS SQL Server : aus 2 Feldern ein 3. Feld berechnen wenn ein Datensatz in die Datenbank gespeichert wird (per Trigger)
Hallo,
ich habe eine Tabelle mit 2 Feldern, die ich in ein drittes Feld zusammenfügen muss (concat) sobald der Datensatz geschrieben wird.
Beispiel Benutzereingabe:
Artikelnr: "4711"
Artikelbezeichnung : "Schraube M3"
Daraus soll auf Datenbankebene (Trigger?) ein 3. Feld (ArtikelnrBezeichnung) automatisch beschrieben werden:
ArtikelnrBezeichnung: "4711 - Schraube M3"
ich habe einen MS SQL Server 2016, vielleicht könnte mir jemand einen Tipp geben wie so ein Trigger aussehen müsste.
Danke.
ich habe eine Tabelle mit 2 Feldern, die ich in ein drittes Feld zusammenfügen muss (concat) sobald der Datensatz geschrieben wird.
Beispiel Benutzereingabe:
Artikelnr: "4711"
Artikelbezeichnung : "Schraube M3"
Daraus soll auf Datenbankebene (Trigger?) ein 3. Feld (ArtikelnrBezeichnung) automatisch beschrieben werden:
ArtikelnrBezeichnung: "4711 - Schraube M3"
ich habe einen MS SQL Server 2016, vielleicht könnte mir jemand einen Tipp geben wie so ein Trigger aussehen müsste.
Danke.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 400043
Url: https://administrator.de/forum/ms-sql-server-aus-2-feldern-ein-3-feld-berechnen-wenn-ein-datensatz-in-die-datenbank-gespeichert-wird-per-400043.html
Ausgedruckt am: 21.04.2025 um 14:04 Uhr
6 Kommentare
Neuester Kommentar
Moin,
Darf man fragen, weshalb die Information redundant abgelegt werden soll?
Wenn es zum anzeigen an anderer Stelle benötigt wird, würde ich eher hier immer mit CONCAT arbeiten, also immer zum zeitpunkt des Selects...
Ansonsten müsste der Trigger ja immer greifen, wenn ein Datensatz eingefügt aber auch aktualisiert wird.
Denn sonst hast du irgendwann mal
ArtikelNr. 4711
Bezeichnung: M3 Schraube
ArtBez: 4711 - M3 Schraube
—> Update
ArtikelNr. 4711
Bezeichnung: M3 Mutter
ArtBez: 4711 - M3 Schraube
Gruß
em-pie
Darf man fragen, weshalb die Information redundant abgelegt werden soll?
Wenn es zum anzeigen an anderer Stelle benötigt wird, würde ich eher hier immer mit CONCAT arbeiten, also immer zum zeitpunkt des Selects...
Ansonsten müsste der Trigger ja immer greifen, wenn ein Datensatz eingefügt aber auch aktualisiert wird.
Denn sonst hast du irgendwann mal
ArtikelNr. 4711
Bezeichnung: M3 Schraube
ArtBez: 4711 - M3 Schraube
—> Update
ArtikelNr. 4711
Bezeichnung: M3 Mutter
ArtBez: 4711 - M3 Schraube
Gruß
em-pie

Wofür man das benötigt hinterfrage ich nicht, ich kann mir schon vorstellen, dass Du zwei Applikatiinen, die darauf zugreifen, nicht ändern kannst oder willst.
Das hier habe ich mal ergoogelt und an Deine Feldnamen angepasst, Du musst nur noch auf den richtigen Tabellennamen umbenennen. Nicht getestet.
CREATE TRIGGER triggername ON tablename FOR INSERT, UPDATE AS
BEGIN IF NOT EXISTS (SELECT * FROM inserted) RETURN
UPDATE tablename
SET ArtikelnrBezeichnung = Artikelnr + ' - ' + Artikelbezeichnung
FROM tablename
WHERE EXISTS (SELECT *
FROM inserted i
WHERE tablename.keycol = i.keycol)
END
Das hier habe ich mal ergoogelt und an Deine Feldnamen angepasst, Du musst nur noch auf den richtigen Tabellennamen umbenennen. Nicht getestet.
CREATE TRIGGER triggername ON tablename FOR INSERT, UPDATE AS
BEGIN IF NOT EXISTS (SELECT * FROM inserted) RETURN
UPDATE tablename
SET ArtikelnrBezeichnung = Artikelnr + ' - ' + Artikelbezeichnung
FROM tablename
WHERE EXISTS (SELECT *
FROM inserted i
WHERE tablename.keycol = i.keycol)
END
Auf keinen Fall Trigger. Das ist immer die letzte Wahl.
Was der TO sucht sind Computed Columns.
Damit kann man eine dynamische Spalte schaffen, die zur Abfragezeit berechnet wird.
Je nach Konstellation kann das allerdings schnell zu Performance Problemen führen.
http://www.sqlservice.se/sql-server-performance-death-by-computed-colum ...
In jedem Fall sollte man wissen was die Auswirkungen sind und prüfen ob es nicht besser ist mit einer View zu arbeiten, bzw an der query was zu Ändern.
Was der TO sucht sind Computed Columns.
Damit kann man eine dynamische Spalte schaffen, die zur Abfragezeit berechnet wird.
Je nach Konstellation kann das allerdings schnell zu Performance Problemen führen.
http://www.sqlservice.se/sql-server-performance-death-by-computed-colum ...
In jedem Fall sollte man wissen was die Auswirkungen sind und prüfen ob es nicht besser ist mit einer View zu arbeiten, bzw an der query was zu Ändern.
Zitat von @SlainteMhath:
Moin,
Trigger lösen je nach dem wie sie erstellt worden sind bei Datenänderungen aus.Moin,
Auf keinen Fall Trigger. Das ist immer die letzte Wahl.
Kannst du das mal näher erklären?Das erste Problem ist, das man hier an alle Eventualitäten denken muss. Insert, Update, delete. Und der Code dazu muss auch passen.
Das schlimmere ist, das Trigger expensive locks auslösen. Das ist einerseits Ressourcenintensiv, aber vor allem , wenn der Code dazu auf einen Fehler läuft, der temporäre Totalausfall für die Table.
Doch das schlimmste: Ein Trigger wird grundsätzlich bei jeder DML Operation zusätzlich eine Logik auslösen, die prüft ob der Trigger jetzt ignoriert oder ausgelöst wird. Das kostet. Wird der Trigger jetzt ausgelöst, entsteht entsprechend der Operation eine DELETED bzw INSERTED Pseudo-Table, die gegen die eigentliche Table gejoined wird.
Kurz: ein Trigger ist fast immer unverhältnissmäßig Ressourcenintensiv und dank der Tablelocks auch gefährlich. Es gibt für nahezu alle Anwendungsmöglichkeiten bessere Aalternativen.
Was der TO sucht sind Computed Columns.
Lustiger Weise ist der Artikel mit "Death by computed Columns" überschrieben Ja nach Use case wären hier auch Trigger oder View das Mittel meiner Wahl.
Leider gibts ja keine näheren Infos zum UseCase. Das was oben beschrieben wird, sollte eigentlich durch ein zusammenfügen der zwei Felder auf Applikationsebene geschehen. Weiss man jetzt halt nicht, ob der TO da Einfluss drauf hat oder nicht. Jedenfalls ist das vom TO gezeichnete Szenario weder ein Fall für Trigger, CCs noch für Views.Aber wenn es so ist, das er einfach nur ein drittes Feld mit den beiden Werten zusammen benötigt, dann ist eine ComputedColumn das Mittel der Wahl. Je nach Bedarf mit oder ohne Persisted
Moin,
da geb ich doch glatt auch noch mal meinen Senf dazu.
Zwar stehe ich Triggern nicht so negativ gegenüber wie SeaStorm, aber schon weil es einfacher, schneller (kein weiterer Zugriff auf die Tabelle) und auch sicherer ist (Trigger kann man auch mal ausschalten), würde ich für so einen Fall, wenn ein Wert aus anderen in derselben Tabelle berechnet wird, eine berechnete Spalte verwenden. Der Link von SeaStorm verweist ja im Grunde nicht darauf, wie so eine Spalte erstellt wird, sondern wie man die Performanceprobleme vermeidet, die durch zur Laufzeit berechnete Werte auftreten können, nämlich indem man den Wert nicht erst bei der Abfrage, sondern schon beim Schreiben berechnet, also genau das, was auch im Trigger passieren würde.
Das was Du suchst, Heinz, wäre mit folgender Zeile erledigt:
alter table <Tabelle> add ArtikelnrBezeichnung as (Artikelnr + ' - ' + Artikelbezeichnung) persisted
<Tabelle> müßte passend ersetzt werden.
Falls Artikelnr oder Artikelbezeichnung NULL sein können, sollte noch ein ISNULL drumrum.
Und falls es doch zur Laufzeit berechnet werden soll, um Platz zu sparen und weil keine Gefahr für die Geschwindigkeit ist, dann müßte "persisted" entfernt werden.
Falls es doch unbedingt ein Trigger sein soll, dann kannst Du ja den von Monto1 verwenden.
Gruß, Mad Max
da geb ich doch glatt auch noch mal meinen Senf dazu.
Zwar stehe ich Triggern nicht so negativ gegenüber wie SeaStorm, aber schon weil es einfacher, schneller (kein weiterer Zugriff auf die Tabelle) und auch sicherer ist (Trigger kann man auch mal ausschalten), würde ich für so einen Fall, wenn ein Wert aus anderen in derselben Tabelle berechnet wird, eine berechnete Spalte verwenden. Der Link von SeaStorm verweist ja im Grunde nicht darauf, wie so eine Spalte erstellt wird, sondern wie man die Performanceprobleme vermeidet, die durch zur Laufzeit berechnete Werte auftreten können, nämlich indem man den Wert nicht erst bei der Abfrage, sondern schon beim Schreiben berechnet, also genau das, was auch im Trigger passieren würde.
Das was Du suchst, Heinz, wäre mit folgender Zeile erledigt:
alter table <Tabelle> add ArtikelnrBezeichnung as (Artikelnr + ' - ' + Artikelbezeichnung) persisted
<Tabelle> müßte passend ersetzt werden.
Falls Artikelnr oder Artikelbezeichnung NULL sein können, sollte noch ein ISNULL drumrum.
Und falls es doch zur Laufzeit berechnet werden soll, um Platz zu sparen und weil keine Gefahr für die Geschwindigkeit ist, dann müßte "persisted" entfernt werden.
Falls es doch unbedingt ein Trigger sein soll, dann kannst Du ja den von Monto1 verwenden.
Gruß, Mad Max