Artikel

Wie man Tabellenzeilen in MySQL vor Überschreiben oder Löschen schützt – zuverlässig, elegant und ohne großen Code

MySQL

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 = 1 ist, 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. titeltitelmeta), 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