Before Update Trigger - auf erwarteten Wert prüfen

jmar83

SQL-Guru
Beiträge
146
Hallo zusammen

Erwartet = expected_hash
Tatsächlich = identify_hash



SET sql_notes = 0;
DROP TRIGGER IF EXISTS ´expected_hash_trigger´;

DELIMITER $$

CREATE TRIGGER ´expected_hash_trigger´
BEFORE UPDATE
ON clientdb_mapping FOR EACH ROW
BEGIN

IF NEW.identify_hash = clientdb_mapping.expected_hash
UPDATE clientdb_mapping SET clientdb_mapping.identify_hash = NEW.identify_hash;
END IF ;



DELIMITER ;

SET sql_notes = 1;




Weiss da jemand weiteres dazu?
 
Werbung:
Auch nix...



SET sql_notes = 0;
DROP TRIGGER IF EXISTS ´expected_hash_trigger´;

DELIMITER //

CREATE TRIGGER ´expected_hash_trigger´
BEFORE UPDATE
ON clientdb_mapping FOR EACH ROW
BEGIN

IF UPDATE.identify_hash = clientdb_mapping.expected_hash
UPDATE clientdb_mapping SET clientdb_mapping.identify_hash = UPDATE.identify_hash;
ELSE
UPDATE clientdb_mapping SET clientdb_mapping.identify_hash = NULL;
END IF ;

END


DELIMITER ;

SET sql_notes = 1;
 
1.) Ein Tabelle hat u.A. 2 Felder: 1x "identify_hash" sowie [neuerdings] "expected_hash"


USE `pf_server`;

INSERT INTO `clientdb_mapping`
(
`expected_hash`,
`identify_hash`,
`db_name`,
`db_version`,
`allnodes`,
`licensedate`,
`licensedatenodes`
)
VALUES
(
NULL,
NULL,
'CUSTOMER_X_DATABASE', # Der Name der zuvor über das Skript erstellten Datenbank
'1.1.1',
'9999',
'2030-01-01',
'2030-01-01'
);



Das oben wäre der "Initialzustand" - beide Felder NULL...

2.) Es sollte ein "before update"-Trigger her, welcher verhindert, dass `identify_hash` ungleich `expected_hash` ist - nach folgender Logik:

- Während `expected_hash` NULL ist, darf `identify_hash` auch NULL sein ("nullable")

- Während `expected_hash` NICHT NULL ist, darf `identify_hash` NULL sein
--> Während `expected_hash` NULL ist, darf `identify_hash` NICHT ungleich NULL sein

- Während `expected_hash` UND `identify_hash` NICHT NULL ist, muss `identify_hash` == `expected_hash` sein


 
dafür gibt es check-constraints, dies sollte Deine Anforderungen erfüllen:

Code:
edb=# create table jmar83 (id int generated always as identity primary key, e_hash text, i_hash text, check (case when e_hash is null then i_hash is null end), check (case when e_hash is not null and i_hash is not null then e_hash = i_hash end));
CREATE TABLE
edb=*# insert into jmar83 (e_hash, i_hash) values (null,null);
INSERT 0 1
edb=*# insert into jmar83 (e_hash, i_hash) values (null,'1');
FEHLER:  neue Zeile für Relation »jmar83« verletzt Check-Constraint »jmar83_check«
DETAIL:  Fehlgeschlagene Zeile enthält (2, null, 1).
edb=*# insert into jmar83 (e_hash, i_hash) values ('2','2');
INSERT 0 1
edb=*# insert into jmar83 (e_hash, i_hash) values ('3','2');
FEHLER:  neue Zeile für Relation »jmar83« verletzt Check-Constraint »jmar83_check1«
DETAIL:  Fehlgeschlagene Zeile enthält (4, 3, 2).
edb=*#
 
Vielen Dank!! :)

Habe den Code nun formatiert und dazu noch

a.) Herausgefunden dass "generated always as identity primary key" scheinbar nicht klappt.

b.) Statt "Text" den Datentyp VARCHAR(60), welcher ursprünglich eingesetzt wurde, verwendet:


Code:
SET SQL_NOTES = 0;

CREATE DATABASE IF NOT EXISTS `pf_server`;
USE `pf_server`;
DROP TABLE IF EXISTS `clientdb_mapping`;

CREATE TABLE IF NOT EXISTS `clientdb_mapping` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `expected_hash` varchar(60) DEFAULT NULL,
  `identify_hash` varchar(60) DEFAULT NULL,
  CHECK (
    CASE
      WHEN expected_hash IS NULL THEN identify_hash IS NULL
    END
  ),
  CHECK (
    CASE
      WHEN expected_hash IS NOT NULL
        AND identify_hash IS NOT NULL THEN expected_hash = identify_hash
    END
  ),
  `db_name` varchar(100) NOT NULL,
  `db_version` varchar(25) NOT NULL DEFAULT '1.1.1',
  `allnodes` int(11) NOT NULL DEFAULT '9999',
  `licensedate` date NOT NULL DEFAULT '2099-01-01',
  `licensedatenodes` date NOT NULL DEFAULT '2099-01-01',
  `timestamp` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `identify_hash` (`identify_hash`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

SET SQL_NOTES = 1;



Nun habe ich 2 Systeme:

- Windows 10 Pro x64 mit MariaDB Version "10.4.12-MariaDB"
"Development" - dort geht alles bestens...

- Debian 9 mit backports-kernel aus Debian 10 und MariaDB Version "10.1.48-MariaDB-0+deb9u2"
"Produktiv" - dort wird mein Struktur-Dump zwar angenommen, die Constraints funktionieren aber nicht...
(WTF?!? :confused:)
 
Dass ich den Dump auf dem prod. Server einspielen kann mit all den CHECK-Constraints - das irritiert mich total... warum kann ich diesen Einspielen, aber funktionieren tut er letztendlich nicht.

Wenn das nicht unterstützt wäre, so sollte ich es ja auch nicht einspielen können. (Denke ich zumindest)
 
Dass ich den Dump auf dem prod. Server einspielen kann mit all den CHECK-Constraints - das irritiert mich total... warum kann ich diesen Einspielen, aber funktionieren tut er letztendlich nicht.

Du solltest auf eine bessere Datenbank wechseln. MySQL & Co verstehen und akzeptieren Check-Constraints. Mehr nicht, auch nicht beachtet oder eingehalten.
 
Danke für dein Feedback.

MariaDB ist nach meiner Erfahrung was Support betrifft (nicht kommerziellen Support, meine eher offene Communities im Netz) viel "schlimmer" als MySQL... wenn man nach mariadb support googelt, so findet man gerade mal die Seite des Herstellers. (Und dein Forum, SEO hat also geklappt ;-))

Das Forum des Herstellers ist aber eher unbrauchbar: The Community

Habe mal einen Bugreport erstellt:

[MDEV-26073] Check-Constraint works on Windows 10 Pro x64 with MariaDB 10.4.12, but not on Debian 9 (backports kernel) on version 10.1.48-MariaDB-0+deb9u2 - Jira

Vielleicht können dir mir dort weismachen warum das kein Bug, sondern ein Feature sei. (LOL)
 
MariaDB ist nach meiner Erfahrung was Support betrifft (nicht kommerziellen Support, meine eher offene Communities im Netz) viel "schlimmer" als MySQL

auch das wäre ein Grund, zu PostgreSQL zu wechseln. Es gibt excellenten kommerziellen Support (z.B. von uns ...), aber auch eine erstklassige Community. Und ja, PostgreSQL hat wirklich coole Features - u.a. daß es wie erwartet funktioniert.
 
Werbung:
Die nächsten Projekte werden wir wohl mir PostgreSQL angeben!

Aber einfach mal schnell migrieren ist leider praktisch unmöglich bei den bestehenden Sachen... :-(
 
Zurück
Oben