AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Änderungs-Logging, Eintragen beim Löschen mit Detail-Tabelle
Thema durchsuchen
Ansicht
Themen-Optionen

Änderungs-Logging, Eintragen beim Löschen mit Detail-Tabelle

Ein Thema von raller09 · begonnen am 1. Okt 2014 · letzter Beitrag vom 2. Okt 2014
Antwort Antwort
raller09

Registriert seit: 7. Nov 2005
38 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

AW: Änderungs-Logging, Eintragen beim Löschen mit Detail-Tabelle

  Alt 1. Okt 2014, 17:17
Hi,

das hilft mir aber nicht weiter oder ist das was ich eigentlich nicht will oder?


es gibt 2 "Verschiedene" Löschungen aus der Detail-Tabelle:

  • Es wird eine oder mehrere Positionen gelöscht.
Dann benötige ich einen "U"-Eintrag in der Export-Tabelle

  • Der Master-DS wird gelöscht und durch den Foreign Key-Constraint werden auch die Positionen gelöscht.
Hier darf das "U" der Positionen nicht nach dem "D" der Master-Tabelle in der Log-Tabelle eingetragen werden.


Kann ich das ohne Umstellung des "on delete cascade;" Constraint erreichen?
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#2

AW: Änderungs-Logging, Eintragen beim Löschen mit Detail-Tabelle

  Alt 1. Okt 2014, 17:28
Frag doch im Trigger der Details bei einer Löschung, ob es den Eltern/Kopfeintrag noch gibt...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Änderungs-Logging, Eintragen beim Löschen mit Detail-Tabelle

  Alt 1. Okt 2014, 19:21
Ich habe das mal für MySQL 5.6 (TIMESTAMP mit Nachkommastellen) zusammengebaut inkl. eines kleinen Tests. Durch die Verwendung des TIMESTAMP(6) kann man im Trigger prüfen, ob es tatsächlich eine Änderung am Datensatz gegeben hat.

Wird nämlich eine Zeile mit identischen Werten aktualisiert, dann wird die TIMESTAMP Spalte nicht aktualisiert, der Trigger wird trotzdem ausgelöst. Mit einem genauen TIMESTAMP kann nun im Trigger zuverlässig (genug ) auf eine Änderung geprüft werden.

Natürlich lösen die Detail-Löschung durch den Foreign-Key keine weiteren Log-Einträge aus -> siehe Trigger auf der Tabelle detail . Das grundlegende Prinzip ist aber für jedes Datenbanksystem gleich
SQL-Code:
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for `master`
-- ----------------------------
DROP TABLE IF EXISTS `master`;
CREATE TABLE `master` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `updated` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `data` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for `detail`
-- ----------------------------
DROP TABLE IF EXISTS `detail`;
CREATE TABLE `detail` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `updated` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `mastid` int(11) NOT NULL,
  `data` varchar(30) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `mastid` (`mastid`),
  CONSTRAINT `setail_master` FOREIGN KEY (`mastid`) REFERENCES `master` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for `log`
-- ----------------------------
DROP TABLE IF EXISTS `log`;
CREATE TABLE `log` (
  `tab` varchar(30) NOT NULL,
  `id` int(11) NOT NULL,
  `act` varchar(1) NOT NULL,
  `org` varchar(30) NOT NULL,
  `ocurred` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DELIMITER //

-- ----------------------------
-- Triggers structure for table detail
-- ----------------------------

CREATE TRIGGER `detail_AI` AFTER INSERT ON `detail` FOR EACH ROW BEGIN
   INSERT INTO
      log ( tab, id, act, org )
   SELECT
      'master', id, 'U', 'detail insert'
   FROM
      `master`
   WHERE
      id = NEW.mastid;
END;//

CREATE TRIGGER `detail_AU` AFTER UPDATE ON `detail` FOR EACH ROW BEGIN
   -- Ist wirklich etwas geändert worden?
   IF OLD.updated <> NEW.updated THEN

      -- Änderung für die ALTE Master-ID eintragen
      INSERT INTO
         log ( tab, id, act, org )
      SELECT
         'master', id, 'U', 'detail update'
      FROM
         `master`
      WHERE
         id = OLD.mastid;

      -- Hat sich die Master-ID geändert?
      IF OLD.mastid <> NEW.mastid THEN
         -- Änderung für die NEUE Master-ID eintragen
         INSERT INTO
            log ( tab, id, act, org )
         SELECT
            'master', id, 'U', 'detail update'
         FROM
            `master`
         WHERE
            id = NEW.mastid;

      END IF;
   END IF;
END;//

CREATE TRIGGER `detail_AD` AFTER DELETE ON `detail` FOR EACH ROW BEGIN
   INSERT INTO
      log ( tab, id, act, org )
   SELECT
      'master', id, 'U', 'detail delete'
   FROM `master`
   WHERE
      id = OLD.mastid;
END;//

-- ----------------------------
-- Triggers structure for table master
-- ----------------------------
CREATE TRIGGER `master_AI` AFTER INSERT ON `master` FOR EACH ROW BEGIN
   INSERT INTO
      log ( tab, id, act, org )
   VALUES
      ( 'master', NEW.id, 'I', 'master insert' );
END;//

CREATE TRIGGER `master_AU` AFTER UPDATE ON `master` FOR EACH ROW BEGIN
   IF NEW.updated <> OLD.updated THEN
      IF NEW.ID = OLD.id THEN
         INSERT INTO
            log ( tab, id, act, org )
         VALUES
            ( 'master', NEW.id, 'U', 'master update' );
      ELSE
         INSERT INTO
            log ( tab, id, act, org )
         VALUES
            ( 'master', OLD.id, 'D', 'master update' ),
            ( 'master', NEW.id, 'I', 'master update' );
      END IF;
   END IF;
END;//

CREATE TRIGGER `master_AD` AFTER DELETE ON `master` FOR EACH ROW BEGIN
   INSERT INTO
      log ( tab, id, act, org )
   VALUES
      ( 'master', OLD.id, 'D', 'master delete' );
END;//

DELIMITER ;

SET FOREIGN_KEY_CHECKS = 1;
Hier ein kleiner Test ...
SQL-Code:
--
-- Test the structure
--

-- Create some master records

INSERT INTO
   `master` ( `data` )
VALUES
   ( 'master 1' ),
   ( 'master' ),
   ( 'master 3' );
   
-- 3 log entries

-- Create some details

INSERT INTO
   `detail` ( `mastid`, `data` )
VALUES
   ( 1, 'detail' ),
   ( 2, 'detail 2' ),
   ( 2, 'detail' ),
   ( 3, 'detail' );
   
-- 4 log entries

-- Do some fake and real updates on master

UPDATE `master` SET `data` = 'master 1WHERE id = 1; -- no real update
UPDATE `master` SET `data` = 'master 2WHERE id = 2; -- real update
UPDATE `master` SET `data` = 'master 3WHERE id = 3; -- no real update

-- 1 log entry ( for touching 3 records )

-- Do some fake and real updates on detail

UPDATE `detail` SET `data` = 'detail 1WHERE mastid = 1; -- 1 real update
UPDATE `detail` SET `data` = 'detail 2WHERE mastid = 2; -- 1 real update, 1 fake update

-- 2 log entries (for touching 3 records )

-- switch the master of detail

UPDATE `detail` SET `mastid` = 3 WHERE mastid = 1;

-- 2 log entries ( for master 1 and master 3 )

-- delete a detail record

DELETE FROM `detail` WHERE `data`='detail';

-- 1 log entry

-- delete a master with details

DELETE FROM `master` WHERE id = 2;

-- 1 log entry
... der dann folgendes LOG produziert
tabidactorgocurred
master1Imaster insert2014-10-01 18:52:36.184279
master2Imaster insert2014-10-01 18:52:36.184279
master3Imaster insert2014-10-01 18:52:36.184279
master1Udetail insert2014-10-01 18:52:36.185614
master2Udetail insert2014-10-01 18:52:36.185614
master2Udetail insert2014-10-01 18:52:36.185614
master3Udetail insert2014-10-01 18:52:36.185614
master2Umaster update2014-10-01 18:52:36.186496
master1Udetail update2014-10-01 18:52:36.187054
master2Udetail update2014-10-01 18:52:36.187564
master1Udetail update2014-10-01 18:52:36.188104
master3Udetail update2014-10-01 18:52:36.188104
master3Udetail delete2014-10-01 18:52:36.188513
master2Dmaster delete2014-10-01 18:52:36.188889
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
raller09

Registriert seit: 7. Nov 2005
38 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: Änderungs-Logging, Eintragen beim Löschen mit Detail-Tabelle

  Alt 2. Okt 2014, 11:32
Hi,

Die Umsetzung von
Frag doch im Trigger der Details bei einer Löschung, ob es den Eltern/Kopfeintrag noch gibt...
entsprechend
Natürlich lösen die Detail-Löschung durch den Foreign-Key keine weiteren Log-Einträge aus -> siehe Trigger auf der Tabelle detail . Das grundlegende Prinzip ist aber für jedes Datenbanksystem gleich
war das, was mir als Idee gefehlt hat:
Select auf die Master-Tabelle
Danke.
Besonders Sir Rufo für den kompletten Aufbau.

Meine Struktur sah ähnlich aus. Ich habe bei mir nur die "Update ohne Änderung"-Prüfung und das Ändern des PKey weg gelassen.
Der insert in die Log-Tabelle wurde nur direkt gemacht...
  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 14:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz