Bachelorarbeit - Wirtschaftsinformatik

Ich möchte hinterher, dass wenn ich mir das Bauteil anzeigen lasse, der Preis/Jahr erscheint. Wie ich das Löse ist ja mir überlassen.
Wie gesagt wollte ich das ganze einfach in einer berechneten Spalten machen, aber die kann nur nicht über mehrere Tabellen gehen. Also hat mir jemand das mit dem View vorgeschlagen. Wenn es mit Triggern natürlich noch besser geht, dann mache ich das.

Ein Mitstudent der mir sonst immer ein wenig unter die Arme gegriffen hat, ist jedoch eher in der MySQL Schiene und kennt keine Trigger. Würdest Du mir grob beschreiben wie ich das mit Triggern hinbekomme?

Ich hätte gedacht, dass dieser Teil der Arbeit leicht werden würde.. ist doch im Prinzip "nur" eine Aufsummierung. =(
 
Werbung:
Ein Trigger müsste bei Aktualisierung eines Datensatzes immer alle anderen damit zusammenhängenden Datensätze aktualisieren. Da kann einem natürlich schonmal was durch die Lappen gehen.

Vorteil:
Er ist sehr flexibel programierbar
Die Werte werden nur bei Veränderungen neu berechnet, bei Views werden sie (unter Umständen) beim Aufruf der View neu berechnet

Wenn du aber schon eine View hast würde ich auch bei dieser bleiben (sofern dein Tool das erlaubt). Einfach über die Datensatz ID die Summe aus der View abfragen und als Spalte bei der Anzeige mit einblenden, dazu muss es ja keine Spalte der Tabelle sein. Die Berechnung einer Summe ist ja kein großer Rechenaufwand.

Vorteil:
Immer aktuelle Daten
Wenig Aufwand
 
SELECT
dbo.ZEinzelteileGeschäftsjahre.JAHR,
SUM(dbo.ZEinzelteileGeschäftsjahre.Z_EG_EP * dbo.ZBauteileEinzelteile.Z_BE_ANZAHL) AS Z_BG_EP,
dbo.ZBauteileEinzelteile.BT_ID,
FROM
dbo.Einzelteile
INNER JOIN dbo.ZBauteileEinzelteile ON dbo.Einzelteile.ET_ID = dbo.ZBauteileEinzelteile.ET_ID
INNER JOIN dbo.ZEinzelteileGeschäftsjahre ON dbo.Einzelteile.ET_ID = dbo.ZEinzelteileGeschäftsjahre.ET_ID
GROUP BY
dbo.ZEinzelteileGeschäftsjahre.JAHR,
dbo.ZBauteileEinzelteile.BT_ID

Ist mein View. Die Tabellen, die dazu benötigt werden habe ich ja schon weiter oben gepostet.
Ich weiß jetzt nicht wie du das mit "einblenden" meinst. Als Ergebis bekomme ich Jahr, BauteilID und den Preis des Bauteils für das Jahr. In dem Programm will ich nun das Bauteil anzeigen und erhalte bestimmte Werte die nur das Bauteil betreffen und wieder andere, die auf Bauteil/Jahr-Basis aufgeteilt sind. Ich brauche also eine Zuweisung von BauteilID und Jahr.
Evtl. sehe ich auch den Wald vor lauter Bäumen nicht. Ich muss bald meine Arbeit abgeben und das Programm wird nicht fertig.. Wenn ich die Berechnungen hinbekomme habe, dann fällt auch noch die Versionierung an x_X

Wie gesagt, diese Verbindung zwischen View und Tabelle bekomme ich nicht geregelt.
 
Wie meinst du das? In Lightswitch braucht man keine Abfragen zu schreiben. Ich habe die Anwendung mit dem SQL Server verbunden und kann auf Basis der Tabellen und Views Masken erstellen. Ich kann dann einstellen was ich sehen will, aber da der View nicht mit der Tabelle verbunden ist, kann er das natürlich nicht einfach in einen Bildschirm packen.
Ich kann auch eine Tabelle mit einem View verbinden. Das geht nur nicht, wenn sie aus einer Quelle stammen.. und das ist bei mit der Fall. Ich denke mal das Microsoft das so geregelt hat, weil man die Verbindung ja auch gleich in der Quelle regeln kann. Nur da fehlt mir jetzt die Erfahrung.
 
Dann ist das scheinbar ein Problem mit der Darstellung in Light Switch. In diesem Fall würde sich tatsächlich ein Trigger anbieten.

Hier mal Trigger im Schnellverfahren erklärt:
Code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Trigger erstellen, existiert er bereits kann CREATE durch ALTER ersetzt werden
CREATE TRIGGER    [dbo].[Triggername]
    ON            [dbo].[Tabellenname]
    AFTER INSERT, UPDATE -- ggf. noch DELETE
AS
-- Bedingung, unter der der Trigger ausgeführt wird
-- (kann auch ganz entfallen, wenn er immer ausgeführt werden soll.
IF        UPDATE(Spalte) -- Guckt, ob die Ausgangsspalte "angefasst" wurde
-- /Bedingung
BEGIN
    SET NOCOUNT ON;
 
    DECLARE    @ID UNIQUEIDENTIFIER, -- Variablen innerhalb des Triggers
            @variable1 INT,
            @variable2 INT
 
    SELECT    @ID = id,
            @variable1 = irgendwas,
            @variable2 = irgendwasanderes
    FROM    INSERTED -- INSERTED und DELETED sind Systemtabellen und behinhalten die Werte,
                    -- die grade eingefügt wurden und die vorher enthalten waren (nur bei AFTER UPDATE gegeben, sonst NULL)
 
    -- Ich Prüfe immer noch ganz gerne, ob sich der Wert in INSERTED und DELETED überhaupt unterscheidet.
    -- UPDATE(Spalte) kann auch zutreffen, wenn der Wert sich nicht verändert hat. Das muss man nicht, sollte
    -- man aber beim Debuggen im Hinterkopf haben.
    -- Vorsicht: NULL Werte können beim abgleich stören
    -- Vorsicht: Trigger können endlos schleifen auslösen
    -- Hinweis: Trigger "feuern" immer nur beim ersten Datensatz. Also wird bei UPDATE Tabelle ein Trigger nur
    -- für den ersten UPDATE vorgang Auslösen.
 
    -- Berechnungen
 
    -- Aktualisieren der zu erechnenden Spalte
    UPDATE    Tabelle
    SET        zuberechnendeSpalte = @variable1
    WHERE    ID = @ID -- Grade eingefügt Spalte wird mit berechnetem Wert gefüllt
    -- ggf. musst du hier mit Schleifen arbeiten, wenn mehrere Datensätze betroffen sind die schon existiert haben
END
GO
 
Okay, das sieht erstmal sehr komplex aus :D

Ich habe jetzt gesehen, dass man Trigger dirket auf eine Tabelle bezieht. Ich verstehe aber noch nicht so ganz was der Trigger überhaupt machen soll bzw. was er kann.

Meine Anforderung ist einfach: Die Ergebnisse des Views sollen in die Tabelle ZBauteileGeschäftsjahre übertragen werden. Dabei sollen 2 Dinge verknüpft/beachtet werden:

1. View.JAHR=Tabelle.JAHR
2. View.BauteilID = Tabelle.BauteilID (Kurzform)

Wenn dann ein Datensatz mit der Kombination Jahr/ID besteht, dann soll er in der Spalte Tabelle.Einzelpreis den View.Einzelpreis einfügen. Wenn noch kein Datensatz besteht, dann soll er einen erstellen und die 3 Spalten Jahr, ID und Einzelpreis ausfüllen.

So stelle ich mir das formell vor. Kann ein Trigger sowas?

An welcher Stelle muss ich den Trigger denn erstellen? Bei der Tabelle oder beim View?
Und wann wird der überhaupt ausgeführt?

Sorry für die vielen Fragen.. ich bin dir sehr dankbar für deine Hilfe und Mühe!!
 
Also ein Trigger hängt immer auf einer Tabelle und nie auf einer View. Er löst aus ("feuert ab") wenn eins von 3 Ereignissen tritt, INSERT, UPDATE oder DELETE. Er tut das wahlweise bevor (FOR) oder nachdem (AFTER) der Datensatz geschrieben, verändert, oder gelöscht wird. In deinem Fall ist ein AFTER Trigger am sinnvollsten.
Der Trigger ist einfach nur ein Script, das auf ein Ereigniss reagiert und T-SQL Code ausführt. Der Code kann fast alles, was auch ein normales T-SQL Script kann. Als Hilfestellung gibt es die Tabellen INSERTED und DELETED. Die beinhalten immer nur den Datensatz, der grade bearbeitet wurde und davon die alte und die neue Version.

Als kleine Besonderheit muss ich erwähnen das der Trigger immer nur beim ersten Datensatz reagiert, ich weiss auch nicht genau warum. Wenn du z.B. UPDATE tabelle SET spalte = 1 machst, und das betrifft mehr als eine Zeile wird der Trigger nur für den ersten Datensatz ausgeführt.

Um auf deinen Fall einzugehen: Die View würde ich in deinem Fall weg lassen. Du musst dir zunächst klar machen, wann sich welche Werte ändern und dann den Trigger feuern lassen. Dieser kann dann auch selbst die notwendige Berechnung machen, die View würde ich nur einsetzen, wenn sie noch weiteren Nutzen hat oder die Berechnung sehr komplex wird.
Außerdem sollte ein Trigger immer nur dann etwas aktuallisieren, wenn unbedingt notwendig.

Ich werde mich nachher mal an dem Code versuchen.

[Edit:]Da Änderungen in mehreren Tabellen überwacht werden müssen und ggf. Einfluss nehmen werde ich mich doch auf die Sicht beziehen und du musst eventuell mehrere Trigger erstellen.
 
Sry schaffe es aus zeitlichen Gründen nicht. Werden auch ziemlich viele Trigger, da du in jeder Tabelle, in der etwas geändert werden kann was für die Berechnung wichtig ist, einen Trigger brauchst. Ich bin aber diese Woche leider unterwegs.
 
Vielen Dank für die Erklärung!

Zum weiteren Nutzen des Views: Das Ergebnis wird auf jeden Fall für weitere Berechnungen gebraucht!
In dieser Dartellung geht es darum den Einzelpreis für ein aus mehreren Einzelteilen bestehendes Bauteil zu berechnen. Der Preis wird dann aber wieder herangezogen um ein Modul zu berechnen, welches aus mehreren Bauteilen besteht.

Daher finde ich es auch sehr schade, dass man in meinem Fall nicht mit berechneten Spalten arbeiten kann. Ich denke, dass es mein Problem um einiges erleichtern würde.
 
So da bin ich nach langer Zeit wieder, hatte viel zu tun ;-)

Ich denke, das Problem an Berechnungen ist die Tatsache, das genau definiert werden muss, wann welche Felder neu berechnet werden sollen. Für einfache Berechnungen, die sich nur aus dem einen Datensatz zusammen setzen und nur dann aktualisiert werden, wenn sich dieser Datensatz ändert, finde ich Views eigentlich ideal und habe sie auch immer dafür genutzt. Problematisch ist halt nur, das dein Frontend diese Informationen aus Views nicht einbinden kann.

Basteln muss man aber immer irgendwo :)
 
Hallo und vielen Dank für alle Tipps die ich hier bisher bekommen habe! Meine Bachelorarbeit habe ich letzten Dienstag abgegeben.
Ich arbeite jetzt aber bis ich exmatrikuliert bin noch an diesem "Projekt" weiter.

Im aktuellen Stand sieht es so aus:
Ich habe auf der Datenbank Shadow-Tabellen angelegt, die per Trigger (einer für Update, Insert und Delete) bei Änderungen mit dem alten Datensatz der Tabelle + User, Zeit usw. gefüllt werden. Es wird also alles was in der Datenbank passiert mitgeloggt.
Das Verbinden der Views konnte ich lösen indem ich Tabellen und Views separat als zwei verschiedene Datenquellen in LightSwitch angegeben habe. Mit diesem Vorgehen war es dann doch möglich Tabellen und Views in dem Programm selber zu verbinden.

Jetzt habe ich aber noch immer das Problem, dass die Versionierung noch nicht so klappt, wie es eigentlich gedacht war. Das Shadow-Tabellen-Konzept loggt jetzt wirklich alles mit und eine Sicht auf diese Daten wäre auch eher unkomfortabel. Was das Controlling wirklich braucht ist folgendes:
Ein Projekt wird angelegt: Projektnummer wird vergeben, Kunde eingetragen, Systeme verknüpft...
Wenn nun alles festgelegt wurde, dann möchte der Controller den Stand dieses Projektes einfrieren und unter einer Version speichern. Projekt "X" soll also die Version "2" bekommen.
Dieser Stand soll dann aber weiterhin verändert werden können. In der Maske soll es dann vom Prinzip her die Möglichkeit geben ein Projekt auszuwählen (Projekt "X") und danach eine Version dieses Projekts (Version "1" für Hauptversion und dann "2", "3" usw. für folgende). Diese Versionierung soll per Button passieren. Die Frage ist jetzt, wie man sowas auf nem SQL Server umsetzen kann. Brauche ich dafür eine gespeicherte Prozedur die ich mit dem Button verknüpfe oder einen Trigger? Ich kann mir sogar vorstellen, dass ich beides brauche. Wenn ich eine Version ziehe, dann muss ich ja nicht nur die Daten aus der Tabelle "Projekt" speichern. Es sind auch alle Verknüpften Tabellen betroffen, wie z.B. ProjekteGeschäftsjahre, ProejtekSysteme, ProjekteModule usw. Das Controlling braucht ein Werkzeug, in dem es möglich ist einen Stand einzufrieren, und diesen trotzdem noch bei Bedarf zu ändern. Wenn das mit der Änderungsanforderung nicht wäre, dann könnte man auch einfach eine Anfrage erstellen, die alle benötigten Werte liefert und dann eine Tabelle damit füllt.

Ich hoffe es ist einigermaßen gut rübergekommen, was ich mir vorstelle. Ich hoffe, dass ich wieder ein paar Tipps von euch bekommen kann! =)

Liebe Grüße

gs3rr4
 
Erstmal zu deiner Log Tabelle: Ich nutze auch eine Log Funktion für mein CRM in dem ich per Trigger Daten in eine Log Tabelle schreibe. Allerdings hat jede Log Tabelle nur folgenden Aufbau:
Code:
CREATE TABLE [dbo].[auf_log](
    [pk] [uniqueidentifier] NOT NULL,
    [fk_auf] [uniqueidentifier] NOT NULL,
    [user] [varchar](13) NOT NULL,
    [feld] [varchar](30) NOT NULL,
    [wert_neu] [varchar](70) NULL,
    [wert_datum_neu] [datetime] NULL,
    [wert_alt] [varchar](70) NULL,
    [wert_datum_alt] [datetime] NULL,
    [aktion] [varchar](10) NOT NULL,
    [wert_key_neu] [uniqueidentifier] NULL,
    [wert_key_alt] [uniqueidentifier] NULL,
    [datum] [datetime] NOT NULL,
PK als künstlichen Primärschlüssel, FK als Schlüssel des geloggten Datensatzes. Die "Wert" Felder beinhalten immer alten und neuen Wert in eine für den Anwender leserlichen Form, auch bei Datum. Wird eine Verknüpfung geändert wird es zu beiden Datensätzen in die Log Tabelle geschrieben und für die Nachvollziehbarkeit bzw. für Filter gibts dann noch die Datums und Key Spalten.

So schreibe ich nicht jedesmal eine komplette Zeile mit vielen identischen Spalten sondern pro geänderter Spalte eine Zeile. Man kann auch Felder kombinieren wie z.B. PLZ Ort um das ganze lesbar zu gestalten oder Felder vom Logging ausnehmen um die Übersicht zu behalten.

Vieleicht hilft dir das bei der Übersicht.

Zu deinem Versionierungsproblem: Das "einfrieren" läßt sich eigentlich leicht über schreibrechte lösen. Für zukünftige Versionen würde ich dann eventuell einen neuen Datensatz in der selben Tabelle anlegen der erstmal den Ursprünglichen kopiert und dann wieder von entsprechenden Personen verändert werden kann.
 
Meine Logging Tabelle sieht ähnlich aus.

Neuer PK
Eine Spalte die angibt ob INSERT, DELETE oder UPDATE ausgeführt wurde
Datum/Uhrzeit
Username
Name der Anwendung, in der die Aktion durchgeführt wurde
Werte vor Änderung

--


Zu deinem Versionierungsproblem: Das "einfrieren" läßt sich eigentlich leicht über schreibrechte lösen. Für zukünftige Versionen würde ich dann eventuell einen neuen Datensatz in der selben Tabelle anlegen der erstmal den Ursprünglichen kopiert und dann wieder von entsprechenden Personen verändert werden kann.

Ja, die Versionen sollte in der selben Tabelle stehen. Aber wie bekomme ich dass Kopieren hin?
Selbst wenn der Datensatz dann kopiert ist und in der Spalte "Version" eine Nummer hochgezählt worden ist, müssen trotzdem alle Verbindungstabellen mit überprüft werden. Auch dort müssen alle Datensätze, welche die alte ProjektID enthalten haben, kopiert werden.
 
Werbung:
Du hast ja vermutlich ein Feld BIT oder etwas vergleichbares das deinen Datensatz fest schreibt. Etwas ähnliches kannst du auch zum anlegen einer neuen Version nutzen, worauf dann ein Trigger reagiert der alle Felder ausliest und den PK ändert sowie die Version hoch zählt und wieder in die DB schreibt. Das ist eigentlich mehr Fleisarbeit als schwierig, zumal es auch bei Anpassungen der Tabelle mit geändert werden muss.
 
Zurück
Oben