AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Trigger -> Änderung in einem DBGrid
Thema durchsuchen
Ansicht
Themen-Optionen

Trigger -> Änderung in einem DBGrid

Ein Thema von Zwirbel · begonnen am 8. Aug 2016 · letzter Beitrag vom 9. Aug 2016
Antwort Antwort
Zwirbel

Registriert seit: 17. Aug 2009
66 Beiträge
 
Delphi 11 Alexandria
 
#1

Trigger -> Änderung in einem DBGrid

  Alt 8. Aug 2016, 15:44
Datenbank: Firbird • Version: 3 • Zugriff über: Seattle 10
Hallo,

für alle Tabellen unserer Datenbank gibt es Felder wie:
Code:
  "Created" TIMESTAMP NOT NULL,
  "Modified" TIMESTAMP NOT NULL,
  "CreatedBy" SMALLINT NOT NULL,
  "ModifiedBy" SMALLINT NOT NULL,
Nun habe ich für diese Felder Trigger eingerichtet die dafür sorgen, dass die entsprechenden Felder je nach Situation angepasst werden.

Hier die Trigger:
Delphi-Quellcode:
/* Trigger für Defaultwerte von Created, Modified, CreatedBy und ModifiedBy */
SET TERM ^;
CREATE OR ALTER TRIGGER TR_TA_TimeTableList_Created_BI FOR TA_TimeTableList ACTIVE BEFORE INSERT
AS BEGIN
  IF (NEW."Created" IS NULL) THEN NEW."Created" = CURRENT_TIMESTAMP;
  IF (NEW."Modified" IS NULL) THEN NEW."Modified" = CURRENT_TIMESTAMP;
  IF (NEW."CreatedBy" IS NULL) THEN NEW."CreatedBy" = 0;
  IF (NEW."ModifiedBy" IS NULL) THEN NEW."ModifiedBy" = 0;
END ^

/* Trigger für Aktualisierung von Modified und ModifiedBy */
CREATE OR ALTER TRIGGER TR_TA_TimeTableList_Modified_BU FOR TA_TimeTableList ACTIVE BEFORE UPDATE
AS BEGIN
  NEW."Modified" = CURRENT_TIMESTAMP;
  NEW."ModifiedBy" = 0;
END ^
SET TERM ;^
Das funktioniert auch prinzipiell. Aber wenn ich nun in einem TDBGrid, das an einem TFDQuery/TDataSource hängt (was an einem TFDConnection hängt), einen Datensatz ändere, zum nächsten springe, dann wird im Grid die Änderung des "Modified" nicht sofort angezeigt, erst wenn man z. B. die Abfrage erneuert. Auf den zweiten Blick ist mir das sogar klar, das das so ist. Aber erwartet hatte ich was anderes, nämlich das im Grid sofort die Änderung zu sehen ist, wenn man was geändert hat und zu einem anderen Datensatz springt.

Wo und wie ist hier der Hebel anzusetzen, dass durch Trigger veränderte Werte in einem Grid angezeigt werden?

TIA, Markus
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Trigger -> Änderung in einem DBGrid

  Alt 8. Aug 2016, 15:55
Du musst die Daten neu laden. Da führt kein Weg dran vorbei.
Eine Hilfe dabei kann POST_EVENT sein.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.351 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Trigger -> Änderung in einem DBGrid

  Alt 8. Aug 2016, 16:00
Um die eigenen Änderungen zu sehen, reicht IMHO ein RefreshRecord nach dem Post.
Manche Komponenten haben auch ein Property, wo man das Verhalten steuern kann, ich kenne aber FDQuery nicht.
Frank Reim
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Trigger -> Änderung in einem DBGrid

  Alt 8. Aug 2016, 16:00
Hallo,
das ist pure Absicht,
du siehst immer die Daten der aktuellen Transaktion (vor den Trigger-Updates).

siehe auch hier
http://stackoverflow.com/questions/1...are-editing-it

Heiko
Heiko

Geändert von hoika ( 8. Aug 2016 um 16:03 Uhr)
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Trigger -> Änderung in einem DBGrid

  Alt 8. Aug 2016, 16:50
Zitat:
das ist pure Absicht,
du siehst immer die Daten der aktuellen Transaktion (vor den Trigger-Updates).
Das ist so nicht korrekt. Die Trigger werden in der aktuellen Transaction ausgeführt. Aber wie DataSpider geschrieben hat muss der aktuelle Record neu eingelesen werden.
Fritz Westermann
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Trigger -> Änderung in einem DBGrid

  Alt 8. Aug 2016, 17:40
Hallo,#
ach so, ich dachte, es geht um ein Mehrbenutzer-System.


Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#7

AW: Trigger -> Änderung in einem DBGrid

  Alt 8. Aug 2016, 17:47
Es gibt einige Zugriffskomponenten, die bieten direkt eine RefreshAfterPost-Option an, wo sie automatisch ein RefreshRecord nach einem Post ausführen.
Refresh = alle Datensätze / RefreshRecord nur der aktuelle Datensatz (dafür wird meißt das WHERE erweitert, um die DatensatzID) ... kommt dann drauf an, wie weit Triger die Daten ändern können und ob es sich auch auf andere Datensätze auswirken kann.

Der Insert-Trigger wäre nicht unbedingt nötig, denn dafür kann man die Default-Werte doch bestimmt auch direkt in der Tabelle definieren.
SQL-Code:
"Created" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"Modified" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"CreatedBy" SMALLINT NOT NULL DEFAULT 0, -- CURRENT_USER?
"ModifiedBy" SMALLINT NOT NULL DEFAULT 0,
Aber warum wird Modified schon beim Insert gesetzt, wo es da doch noch garnicht editiert sein kann?



Na dann hoffe ich mal, dass dein Programm im Laufe seines Lebens nicht mehr als 32.767 User kennt
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 8. Aug 2016 um 17:51 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#8

AW: Trigger -> Änderung in einem DBGrid

  Alt 8. Aug 2016, 18:47
SQL-Code:
"Created" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"Modified" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"CreatedBy" SMALLINT NOT NULL DEFAULT 0, -- CURRENT_USER?
"ModifiedBy" SMALLINT NOT NULL DEFAULT 0,
Aber warum wird Modified schon beim Insert gesetzt, wo es da doch noch garnicht editiert sein kann?



Na dann hoffe ich mal, dass dein Programm im Laufe seines Lebens nicht mehr als 32.767 User kennt
Wenn sich hinter CreatedBy/ModifiedBy eine unique ID aus einem Generator verbirgt, könnte das aber ganz schnell, ganz eng werden.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Zwirbel

Registriert seit: 17. Aug 2009
66 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Trigger -> Änderung in einem DBGrid

  Alt 9. Aug 2016, 09:00
Es gibt einige Zugriffskomponenten, die bieten direkt eine RefreshAfterPost-Option an, wo sie automatisch ein RefreshRecord nach einem Post ausführen.
Welche Komponente meinst du hier konkret? In TFDQuery oder TDBGrid kann ich eine solche Option nicht finden. Es geht auch wirklich um eine Option oder um irgendeinen Event?

Der Insert-Trigger wäre nicht unbedingt nötig, denn dafür kann man die Default-Werte doch bestimmt auch direkt in der Tabelle definieren.
Wie sollte ein Defaultwert für ein Datum/Zeit-Feld (wie "Created"/"Modified") aussehen? Genauso die Frage, wie es für "CreatedBy"/"ModifiedBy" aussehen könnte? Ich habe in der Richtung schon gesucht, ich bräuchte quasi so etwas wie eine Variable die meine Anwendung setzen kann, also wenn sich ein Anwender an unserer Anwendung (mit der UserId=5) anmeldet, dass ich diese "5" irgendwie an Firebird übergeben kann, dass es bei den Triggern dann für "CreatedBy"/"ModifiedBy" diesen Wert nimmt. Noch völlig unbeleckt von den Möglichkeiten einer SQL-Datenbank wüsste ich nicht wie das (natürlich möglichst elegant) gehen soll. Klar, ich könnte mir jetzt eine Pseudo-Tabelle basteln "ActiveUser" mit einem einzigen Feld drin "ActiveUserId". Beim Anmelden speichere ich dann in der Tabelle einen Datensatz mit der "5", um im obigen Beispiel zu bleiben. Dann müsste ich in meinen Triggern diese Tabelle "ActiveUser" abfragen. Aber da dreht sich mir irgendwie der Magen um, das wäre doch ziemlicher Unsinn. Wie geht es eleganter/performanter?

SQL-Code:
"Created" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"Modified" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"CreatedBy" SMALLINT NOT NULL DEFAULT 0, -- CURRENT_USER?
"ModifiedBy" SMALLINT NOT NULL DEFAULT 0,
"CURRENT_USER" ist ein VarChar. Ich möchte auf keinen Fall in meinen Tabellen pro Datensatz eine Zeichenkette speichern mit dem User als String, das hielte ich für keine gute Idee. Außerdem wäre "CURRENT_USER" ja der aktuelle User der Firebird-Datenbank. Ich würde gerne den aktuellen User (als Integer) aus unserer eigenen Userverwaltung verwenden. So mache ich das in unserer aktuellen Anwendung auch. Da ich da aber keine Trigger verwenden kann, wird diese ganze "Created"...-Gedöns alles zu Fuß für jedes einzelne TTable/TQuery das auf einem Formular pappt erledigt. Da dachte ich nun, wunderbar mit SQL geht das ja alles viel einfacher, das erledigt quasi die Datenbank im Hintergrund.

Aber warum wird Modified schon beim Insert gesetzt, wo es da doch noch garnicht editiert sein kann?
Da hast du Recht, das ist Unfug.

Na dann hoffe ich mal, dass dein Programm im Laufe seines Lebens nicht mehr als 32.767 User kennt
Bei einem Kunden hat es ca. 50 User, bei den anderen <= 20. Da ist man mit dem SMALLINT auf der sicheren Seite.

TIA, Markus
  Mit Zitat antworten Zitat
Zwirbel

Registriert seit: 17. Aug 2009
66 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Trigger -> Änderung in einem DBGrid

  Alt 9. Aug 2016, 09:11
SQL-Code:
"Created" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"Modified" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"CreatedBy" SMALLINT NOT NULL DEFAULT 0, -- CURRENT_USER?
"ModifiedBy" SMALLINT NOT NULL DEFAULT 0,
Aber warum wird Modified schon beim Insert gesetzt, wo es da doch noch garnicht editiert sein kann?

Na dann hoffe ich mal, dass dein Programm im Laufe seines Lebens nicht mehr als 32.767 User kennt
Wenn sich hinter CreatedBy/ModifiedBy eine unique ID aus einem Generator verbirgt, könnte das aber ganz schnell, ganz eng werden.
Ja, die IDs kommen aus einem Generator, aber in unserer Anwendung tummeln sich nur sehr wenige (<50) Anwender. Habt ihr denn Kunden mit mehr als 32.767 Anwendern in einer Datenbank-Anwendung? Vermutlich schon, sonst wärt ihr nicht erstaunt, dass ich da mit einem SMALLINT aus komme. Mir würde auch ein BYTE reichen, wenn es das gäbe.

Gruß, Markus
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz