varchar Feld während des Updates vergleichen

tadeus

Benutzer
Beiträge
14
Hallo,

ich bin neu hier und auf der Suche nach einer Lösung für folgende Sache:

Ich habe in einer Tabelle gefüllte "varchar" und "text" Felder. Bei einem Update dieser Felder soll vorher verglichen werden, ob sich der Wert im Update von dem bestehenden Wert in der Tabelle geändert hat. Falls sich was geändert hat, soll ein Wert in einem "int" Feld gesetzt werden.

Kann ich das mit sql lösen, oder geht das nur mit einem vorhergehenden select und anschließenden Vergleich im Programmcode?

Vielen Dank vorab

Grüße
 
Werbung:
Das kann ich dir nicht sagen. Da hätte ich mich vorher schlau machen müssen. Ich bin da flexibel. Ich muss mich jedoch nun mit MariaDB anfreunden.

Wie läuft denn das in PostgreSQL mit dem Trigger in meinem Fall?
 
Der normale Weg:

Code:
test=# create table tadeus (id int primary key, data text, update_count int default 0);
CREATE TABLE
test=*# create or replace function update_trigger() returns trigger as $$begin if old.data != new.data then new.update_count := new.update_count + 1; end if; return new; end;$$language plpgsql;
CREATE FUNCTION
test=*# create trigger trg_update before update on tadeus for each row execute procedure update_trigger();
CREATE TRIGGER
test=*# insert into tadeus (id, data) values (1, 'test 1');
INSERT 0 1
test=*# insert into tadeus (id, data) values (2, 'test 2');
INSERT 0 1
test=*# select * from tadeus ;
 id |  data  | update_count
----+--------+--------------
  1 | test 1 |  0
  2 | test 2 |  0
(2 rows)

test=*# update tadeus set data = 'neu' where id = 2;
UPDATE 1
test=*# select * from tadeus ;
 id |  data  | update_count
----+--------+--------------
  1 | test 1 |  0
  2 | neu  |  1
(2 rows)

test=*# rollback;
ROLLBACK
test=#

Hat den Nachteil, bei JEDEM Insert gefeuert zu werden. Besser: ein conditional TRIGGER:

Code:
test=# create table tadeus (id int primary key, data text, update_count int default 0);
CREATE TABLE
test=*# create or replace function update_trigger() returns trigger as $$begin new.update_count := new.update_count + 1; return new; end;$$language plpgsql;
CREATE FUNCTION
test=*# create trigger trg_update before update on tadeus for each row when (old.data != new.data) execute procedure update_trigger();
CREATE TRIGGER
test=*# insert into tadeus (id, data) values (1, 'test 1');
INSERT 0 1
test=*# insert into tadeus (id, data) values (2, 'test 2');
INSERT 0 1
test=*# update tadeus set data = 'neu' where id = 2;
UPDATE 1
test=*# select * from tadeus ;
 id |  data  | update_count
----+--------+--------------
  1 | test 1 |  0
  2 | neu  |  1
(2 rows)

Wer sieht den Unterschied? Die Prüfung erfolgt nicht innerhalb des Triggers und damit bei JEDEM Update, sondern schon bei der Definition des Triggers. Daher feuert dieser nur dann, wenn es wirklich nötig ist. Bei komplexeren Triggern durchaus ein Vorteil
 
Ich hab mich jetzt mal an nem Trigger probiert. Bisher kannte ich das noch nicht.

Code:
CREATE TRIGGER `table1_before_update` BEFORE UPDATE ON `table1` FOR EACH ROW BEGIN
IF NEW.Bezeichnung1 != OLD.Bezeichnung1 THEN
    SET table1.oldBezeichnung1 = OLD.Bezeichnung1, table1.changed = 1, table1.changeDate = now() WHERE ID = NEW.ID;
END IF;

END

Um das mal kurz zu erklären was ich machen möchte. Bei einem Update von Bezeichnung1 soll verglichen werden ob sich Bezeichnung1 überhaupt geändert hat.
Falls es sich geändert hat soll die bestehende Bezeichnung1 nach oldBezeichnung1 kopiert werden, changed auf 1 und das changeDate gesetzt werden.
Falls sich nichts geändert hat, kann das Update weggeworfen werden.

Bin ich damit schon halbwegs auf dem richtigen Weg?
 
Normalerweise (zumindest bei MSSQL) kannst du old und new nicht ändern, nur abfragen.

Ich kenne jetzt aber nur die MS-Syntax wirklich gut und die ist ziemlich anders als bei PG und vermutlich auch als bei MySQL.
 
ich möchte doch old oder new garnicht ändern, ich möchte nur new vergleichen, old in ein anderes Feld kopieren und new in Bezeichnung1 setzen
 
Ich hab jetzt doch was lauffähiges zusammengeschustert:
Code:
BEGIN
    IF NEW.Bezeichnung1 != OLD.Bezeichnung1 THEN
        SET NEW.oldBezeichnung1 = OLD.Bezeichnung1, NEW.changed = 1, NEW.changeDate = now();
    END IF;
END

Im Moment ist es ja noch, dass wenn sich die Bezeichnung nicht geändert hat, er trotzdem das Update macht und den Bezeichnung1 mit dem selben Wert nochmal überschreibt. Kann ich hier sowas wie ein break; ins ELSE reinsetzen?
 
Werbung:
Zurück
Oben