[MSSQL] Trigger einrichten

Bububoomt

ohne Vertrauen
ID: 10361
L
28 April 2006
19.666
769
Hallo,

ist es möglich mit einem Trigger eine neue Spalte in einer anderen Tabelle einzufügen?

Ich möchte, wenn in Tabelle A eine neue Zeile eingefügt wird, soll in Tabelle B eine neue Spalte eingefügt werden.

Dabei soll der Spaltenname dann den "W"+Primary von A tragen.

Also wird in A Zeile 1 eingetragen so wird in B die Spalte W1 angelegt.

Sollte doch gehen oder? Habe Trigger bisher sehr selten genutzt.
 
Soweit ich weiß ist das nicht möglich, da du einen Trigger der eine neue Spalte einfügt nicht auslösen lassen kannst durch insert,delete oder update. Trigger die sowas machen kannst du aber bei create, drop und sowas anwenden glaube ich.
 
Beim Einfügen einer Zeile (DML) willst du per Trigger automatisch die Struktur einer anderen Tabelle ändern (DDL)? Du solltest mal genauer beschreiben, was du vorhast denn - dafür lege ich meine Hand ins Feuer - hast du ein miserables Datenbankdesign und wahrscheinlich schon die 1. Normalform verletzt.
 
Tabelle IWaehrungen
WID, Name, WCode ....

Tabelle Konto
UID, W1,W2,W3....

So habe ich in einer Zeile alle Daten eines Users, statt x Zeilen wenn ich
UID, WID, Betrag
nutzen würde.
 
Naja was ist Performanter und besser/schöner zu Handeln? Eine Zeile oder X Zeilen?

Was ist besser x Zeilen a y spalten oder x*(y-1) Zeilen a 3 spalten?
Z.B. (A)1000 *6 Spalten oder (B)5000* 3 Spalten?

Zudem könnten die 5 spalten (A) Unterschiedlich sein (Decimal mit unterschiedlicher Nachkommastelle), die 3. Spalte (B) wäre immer gleich.

Was ist leichter für die DB?
Neue Spalte bei X Zeilen einfügen oder X Zeilen a 3 Spalten einfügen?
 
Datenbanksysteme sind dafür gemacht, auch mit vielen Zeilen klarzukommen. Und eine Tabellenstruktur sollte immer so starr wie irgend möglich sein.

Stell Dir doch mal vor, was passiert, wenn Du eine neue Zeile einfügst. Die kann vereinfacht gesagt, hinten an alles bestehende angehängt und im Index vermerkt werden.
Eine neue Spalte hingegen muss bei jeder Zeile hinzugefügt werden, dadurch muss die gesamte Tabelle (inkl. der dahintersteckenden Datei) neu aufgebaut werden.

Welches von beiden performanter ist, dürfte eigentlich auf der Hand liegen.

Ich würde an Deiner Stelle auch mal den Einwand von ice-breaker aufgreifen und prüfen, inwieweit sich Dein Ansatz mit den Normalformen verträgt.
 
Aber die DB wird dadurch auf jeden Fall größer und wie geschrieben, ist die Spalte dann immer gleich.
So kann ich wenigstens die Spalte noch variabel halten.

Klar sind DBs optimiert, aber es gibt ja einen Unterschied in der Geschwindigkeit sonst müssten wir ja nicht drüber hier diskutieren.

Ich weiß ja nicht wie die DB sowas strukturiert. Ich weiß nur, das wenn ich mit MSSQL-Manager eine Spalte anfügen geht das Ratz fatz, wenn ich die mitten rein packen will geht es langsam, oder je nach Tabelle auch gar nicht.

Das Einfügen würde vermutlich auch nur einmal im Jahr passieren, wenn über Haupt!?

*edit*
Einfügen von 40k Zeilen, 2 Spalten >5-6 Sek.
Einfügen Spalte bei 160k Zeilen : 0 Sek.

K.A. wie es bei weiteren Operationen im Anschluss aussieht?


*edit2*
Und wie sieht es dann mit Abfragen wie folgenden aus:
Select count(w1) where w1>100 VS Select count(Wert) where wid=1 and Wert>100
 
Zuletzt bearbeitet:
Eine neue Spalte hingegen muss bei jeder Zeile hinzugefügt werden, dadurch muss die gesamte Tabelle (inkl. der dahintersteckenden Datei) neu aufgebaut werden.

*edit*
Einfügen von 40k Zeilen, 2 Spalten >5-6 Sek.
Einfügen Spalte bei 160k Zeilen : 0 Sek.

(Abgesehen davon dass ich nicht verstehe was 2 Spalten hier bedeuten soll da deine Tabellenstruktur mind. 3 Spalten zeigte) scheint hier etwas nicht ganz stimmen zu können. Und zwar die 2. Zeit mit 0 Sekunden. Ich hab jedenfalls noch nie gesehen dass 160k Zeilen in 0 Sekunden bearbeitet wurden.
Entweder hast du dich da vermessen oder die Datenbank hat die einzelnen Zeilen nicht verändert (ich weiß nicht in wie weit das bei MSSQL so möglich ist?)

Jedenfalls bin ich der Meinung dass deine Tabellenstruktur, wenn ich sie richtig verstanden habe, nicht normalisiert ist (siehe oben ice-breaker und tleilax) und so ein Trigger wie du ihn dir vorstellst funktioniert nicht, du solltest also deine Struktur noch mal überdenken, an die Normalformen anpassen und dann das so benutzen und nicht versuchen wegen eines (deiner Meinung nach) Performance-Vorteils nicht die Normalformen einzuhalten ;)
 
Habe im MSSQL Managmentstudio das gemacht und der Zeigt an wie lange ein Befehl gedauert hat, also ich habe somit nicht falsch gemessen, wenn dann das MSSQl MS.

Ich weiß auch nicht wie die Datenbank das handhabt, aber ich habs mehrfach gemacht und mehrere Spalten hinzugefügt und die waren sofort angelegt. Habe auch einen Standartwert angelegt um zu testen.

Kann es sien, das die DB die Struktur ja speichert und die Spalten dann gar nicht berührt? Diese wird dann nur beim nächsten Update geändert?

Also so wie wenn ich in einer Excel einfach nur die erste Reihe ändere und einen Namen vergebe...
Die Zeilen bleiben halt erst mal leer?

k.a.

Naja, wenn ich ein Performancegewinn habe dadurch das ich die Normalform nicht einhalte, werde ich das schon machen.
Das mache ich dann vor allem wenn ich dann etwas von 3 min auf 10 Sek. verkürzen kann.
 
...Kann es sien, das die DB die Struktur ja speichert und die Spalten dann gar nicht berührt? Diese wird dann nur beim nächsten Update geändert?
Ja.

Hinzufügen von NOT NULL-Spalten als Onlinevorgang

In SQL Server 2012 Enterprise Edition ist das Hinzufügen einer NOT NULL-Spalte mit einem Standardwert ein Onlinevorgang, wenn der Standardwert eine Laufzeitkonstante ist. Dies bedeutet, dass der Vorgang unabhängig von der Anzahl von Zeilen in der Tabelle nahezu sofort abgeschlossen wird. Dies liegt daran, dass die vorhandenen Zeilen in der Tabelle während des Vorgangs nicht aktualisiert werden. Stattdessen wird der Standardwert nur in den Metadaten der Tabelle gespeichert, und in Abfragen wird bei Bedarf nach dem Wert gesucht und auf diese Zeilen zugegriffen. Dieses Verhalten ist automatisch. ...

https://msdn.microsoft.com/de-de/library/ms190273.aspx
 
Mit Triggern kriegst du das aber nicht hin da musst du dir erstmal was anderes ausdenken und dann schauen ob es wirklich soviel bringt ;)

natürlich geht das. Wieso sollte es nicht gehen? Du kannst bei triggern alles machen was du auch sonst mit SQL machen kannst.


@apolle
ok, also wie ich es mir gedacht habe.
 
natürlich geht das. Wieso sollte es nicht gehen? Du kannst bei triggern alles machen was du auch sonst mit SQL machen kannst.

Hast du es programmiert? 8O

Du willst einen Trigger machen der bei einem Insert Befehl loslegt, und der Trigger soll dann einen Alter Table Befehl machen.
Das funktioniert aber nicht, da ein Trigger der bei Insert loslegt nur Insert, Delete oder Update ausführen kann.
Ein Trigger der Alter Table ausführt, muss auch durch einen anderen alter, create, drop oder was es noch so gibt ausgelöst werden, aber nicht durch ein insert, update oder delete.
Du willst also DML und DDL Trigger mischen...

Müsste sich hier irgendwo finden lassen, warum es nicht geht: https://msdn.microsoft.com/de-de/library/ms189799.aspx
 
So wie ich es sehe, kann ich jeglichen SQL-Befehl in einem Trigger ausführen.

Und das hat nun auch geklappt. Nach Anlegen einer neuen Zeile wird nun in einer anderen Tabelle eine Spalte angelegt. habe nur 2 Anlaufe für die korrekte Syntax gebraucht.
 
Und der ganze Quatsch nur, weil du denkst, dass es Performancevorteile hat :roll: Komplett ohne es genauer zu untersuchen, ohne überhaupt ein Problem zu haben die wichtigste Regel im DB-Design zu verltzten - ja du bist ein super DB-Optimierer!
 
Würdest du immer Regeln einhalten, auch dann wenn diese schlecht sind? Und das diese Regeln nicht immer gut sind, das solltest du doch wissen, die 1NF kann dazu führen, das die DB langsamer ist.

Wenn ich es nur denke, zeig mir doch , das ich falsch liege.

Sollte man Probleme schon umgehen bevor man die hat oder doch erst hinter her?8O
 
Würdest du immer Regeln einhalten, auch dann wenn diese schlecht sind? Und das diese Regeln nicht immer gut sind, das solltest du doch wissen, die 1NF kann dazu führen, das die DB langsamer ist.
Du hast bis jetzt keine Beweis für deine These gebracht, dass die Verletzung der 1. NF schneller ist, du vermutest es einfach. Und natürlich würde ich keine sinnlose Regel einhalten, aber die Normalformen wurden aus sehr gutem Grund erschaffen, die hat sich nicht ein Volltrunkener Informatiker eines Nachts ausgedacht um Schüler/Studenten zu ärgern oder damit sich bestimmte Personen profilieren können.
Die 2. und 3. NF darfst du gerne bei einem guten Grund verletzten (z.B. Shadow Values um Aggregierungen vorberechnet vorzuhalten), aber die 1. NF verletzte man nicht!
 
Du hast bis jetzt keine Beweis für deine These gebracht, dass die Verletzung der 1. NF schneller ist, du vermutest es einfach. Und natürlich würde ich keine sinnlose Regel einhalten, aber die Normalformen wurden aus sehr gutem Grund erschaffen, die hat sich nicht ein Volltrunkener Informatiker eines Nachts ausgedacht um Schüler/Studenten zu ärgern oder damit sich bestimmte Personen profilieren können.
Die 2. und 3. NF darfst du gerne bei einem guten Grund verletzten (z.B. Shadow Values um Aggregierungen vorberechnet vorzuhalten), aber die 1. NF verletzte man nicht!

Bevor ich was beweise, doofe Frage, verletze ich die 1. NF eigentlich überhaupt?
Ist ja sehr lange her bei mir, aber heißt 1 .NF nicht, das ich ich der DB keine Redundanten Daten habe?
Habe ich redundante Daten?