Löschsperre für bestimmte Sets

PeterS

Aktiver Benutzer
Beiträge
27
Kann ich irgendwie (per Trigger oder so) verhindern, dass bestimmte Datensätze in einer Tabelle gelöscht werden? Ich denke z.B. an ein J/N-Feld "Loeschsperre", das durch einen delete-Trigger abgefragt wird.

Ziel ist es, bestimmte Geschäftsgang-Daten - unabhängig von den Benutzerrechten - unkaputtbar zu machen.
 
Werbung:
In PG könntest Du eine RULE definieren:

Code:
test=# create table foo (id serial primary key, data text, do_not_delete bool default false);
CREATE TABLE
test=*# insert into foo values (1, 'data 1', false);
INSERT 0 1
test=*# insert into foo values (2, 'data 2', true);
INSERT 0 1
test=*# insert into foo values (3, 'data 3', true);
INSERT 0 1
test=*# insert into foo values (4, 'data 4', false);
INSERT 0 1
test=*# create rule do_not_delete as on delete to foo where do_not_delete do instead nothing;
CREATE RULE
test=*# select * from foo;
 id |  data  | do_not_delete
----+--------+---------------
  1 | data 1 | f
  2 | data 2 | t
  3 | data 3 | t
  4 | data 4 | f
(4 rows)

test=*# delete from foo where id = 1;
DELETE 1
test=*# select * from foo;
 id |  data  | do_not_delete
----+--------+---------------
  2 | data 2 | t
  3 | data 3 | t
  4 | data 4 | f
(3 rows)

test=*# delete from foo where id = 2;
DELETE 0
test=*# select * from foo;
 id |  data  | do_not_delete
----+--------+---------------
  2 | data 2 | t
  3 | data 3 | t
  4 | data 4 | f
(3 rows)

test=*#

Allerdings gibt es innerhalb der Entwickler von PG Überlegungen, Rules nicht mehr zu unterstützen, ein TRIGGER ginge hier auch. PG kann TRIGGER auch an WHERE-Conditions binden.

Code:
test=# create table foo (id serial primary key, data text, do_not_delete bool default false);
CREATE TABLE
test=*# insert into foo values (1, 'data 1', false);
INSERT 0 1
test=*# insert into foo values (2, 'data 2', true);
INSERT 0 1
test=*# insert into foo values (3, 'data 3', true);
INSERT 0 1
test=*# insert into foo values (4, 'data 4', false);
INSERT 0 1
test=*# create or replace function do_not_delete() returns TRIGGER as $$begin return NULL;end;$$language plpgsql;
CREATE FUNCTION
test=*# create trigger trg1 before delete on foo for each row when (old.do_not_delete) execute procedure do_not_delete();
CREATE TRIGGER
test=*# select * from foo;
 id |  data  | do_not_delete
----+--------+---------------
  1 | data 1 | f
  2 | data 2 | t
  3 | data 3 | t
  4 | data 4 | f
(4 rows)

test=*# delete from foo where id = 1;
DELETE 1
test=*# select * from foo;
 id |  data  | do_not_delete
----+--------+---------------
  2 | data 2 | t
  3 | data 3 | t
  4 | data 4 | f
(3 rows)

test=*# delete from foo where id = 2;
DELETE 0
test=*# select * from foo;
 id |  data  | do_not_delete
----+--------+---------------
  2 | data 2 | t
  3 | data 3 | t
  4 | data 4 | f
(3 rows)

test=*#

Weitere Möglichkeiten wäre der Einsatz von RLS (Row Level Security) oder generell den Zugriff auf die Tabelle sperren (REVOKE) und solche Aktionen in Funktionen (security definer) kapseln, die dann prüfen, ob gelöscht werden darf oder nicht.
 
Werbung:
Ein Trigger geht in MSSQL auf jedenfall. Was soll denn genau passieren wenn ein Datensatz nicht gelöscht werden darf, soll dann nur der eine Datensatz nicht gelöscht werden oder die ganze DELETE Anweisung verworfen werden? Soll die Datenbank einen Fehler liefern oder soll sie einfach nicht löschen?
 
Zurück
Oben