Wie man Tabellenzeilen in MySQL vor Überschreiben oder Löschen schützt – zuverlässig, elegant und ohne großen Code
Wer Datenbanken betreibt, kennt das Dilemma:
Man kann noch so saubere Oberflächen oder API-Checks einbauen – wenn jemand direkten SQL-Zugriff hat oder ein Bug in der Anwendung steckt, können sensible Daten überschrieben oder gelöscht werden.
Gerade in Inventar-, Shop- oder ERP-Systemen gibt es Datensätze, die man nie verlieren oder versehentlich ändern darf.
Ein klassisches Beispiel: „Produktstammdaten“, die von automatisierten Prozessen weiterverarbeitet werden.
Die Lösung ist ein Schutz auf Datenbankebene.
2. Der richtige Weg: MySQL/MariaDB-Trigger nutzen
Ein Trigger ist ein Stück SQL-Logik, das automatisch ausgeführt wird, sobald ein bestimmtes Ereignis (z. B. UPDATE oder DELETE) auftritt.
Damit lassen sich Aktionen unterbinden, bevor sie Schaden anrichten.
Die Idee ist einfach:
- In der Tabelle gibt es eine Spalte
Gesperrt(TINYINT oder BOOLEAN). - Wenn
Gesperrt = 1ist, dürfen UPDATE und DELETE nicht mehr ausgeführt werden.
3. Umsetzung in der Praxis
Schritt 1: Spalte für Sperrstatus hinzufügen
ALTER TABLE titelmeta ADD COLUMN Gesperrt TINYINT(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Schreibschutz aktiv';
Schritt 2: Trigger für Updates
DELIMITER //
CREATE TRIGGER prevent_update_when_locked
BEFORE UPDATE ON titelmeta
FOR EACH ROW
BEGIN
-- Prüfen, ob die Zeile VOR dem Update gesperrt war.
IF OLD.Gesperrt = 1 THEN
-- Wenn die Sperre BEIBEHALTEN wird (d.h., NEW.Gesperrt ist auch 1),
-- dann wird JEDE Änderung (außer dem Entsperren) verhindert.
IF NEW.Gesperrt = 1 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Inhaltliche Änderung nicht erlaubt: Die Zeile ist gesperrt (Gesperrt=1). Entsperren Sie die Zeile zuerst.';
END IF;
END IF;
END//
DELIMITER ;
Schritt 3: Trigger für Löschversuche
DELIMITER //
CREATE TRIGGER prevent_delete_when_locked
BEFORE DELETE ON titelmeta
FOR EACH ROW
BEGIN
-- Überprüfen, ob die zu löschende Zeile ('OLD') gesperrt ist
IF OLD.Gesperrt = 1 THEN
-- Wenn die Spalte 'Gesperrt' den Wert 1 hat, wird das Löschen verhindert
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Löschen nicht erlaubt: Diese Zeile ist gesperrt (Gesperrt = 1).';
END IF;
END//
DELIMITER ;
Damit ist der Schutz auf Datenbankebene aktiv – unabhängig davon, welche Anwendung oder API das SQL ausführt.
4. Erweiterung: Schutz synchron auf verknüpfte Tabellen anwenden
Wenn es zu einer 1:1-Beziehung kommt (z. B. titel ↔ titelmeta), kann man in beiden Tabellen die Spalte Gesperrt einführen.
Beim Sperren wird dann synchronisiert:
UPDATE titel t
INNER JOIN titelmeta tm ON t.ID = tm.titel_ID
SET t.Gesperrt = 1, tm.Gesperrt = 1
WHERE tm.Bestellnummer = 12345;
Damit bleibt der Status konsistent – egal, über welche Tabelle man Daten ändert.
5. Frontend-Integration (optional)
Im Backend oder der Web-Oberfläche kann man die Spalte Gesperrt einfach anzeigen:
Ein Häkchen oder Schloss-Symbol genügt.
Ein Doppelklick auf das Symbol kann über einen AJAX-Aufruf den Sperrstatus umschalten.
Beispiel für Tabulator.js 2.x:
{
title: "G.",
field: "Gesperrt",
width: 40,
align: "center",
sorter: "boolean",
formatter: function (value) {
return value
? "<i class='fa fa-lock' style='color:#d9534f'></i>"
: "<i class='fa fa-unlock' style='color:#5cb85c'></i>";
},
cellDblClick: function (e, cell, value, data) {
const neu = !value;
cell.setValue(neu);
$.ajax({
url: "locktoggle.php",
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({ bestellnummer: data.Bestellnummer, gesperrt: neu })
});
}
}
Damit kann man direkt aus der Tabelle heraus Titel sperren oder entsperren – komfortabel und sicher.
6. Fazit
- Anwendungslogik kann Fehler haben – Trigger nicht.
- Sperrlogik auf Datenbankebene ist die einzige wirklich verlässliche Methode, um Daten dauerhaft vor ungewollten Änderungen zu schützen.
- Die Implementierung ist simpel, robust und systemunabhängig.
Wer wichtige Daten schützt, sollte das immer dort tun, wo sie leben: in der Datenbank selbst.
0 Kommentare