Hallo! Gestern habe ich Stunden mit einem Statement verbracht und dachte schon, ich hätte es gelöst. Dann hab ich einen Testfall gefunden, bei dem es versagt. Heute habe ich schon wieder zwei Stunden daran herumgeknobelt und komme auf keine vernünftige Lösung.
Es handelt sich um ein Berechtigungssystem. Es gibt eine Tabelle Benutzer, eine Tabelle BenutzerRecht (für die n:m Beziechung) und eine Tabelle Recht.
Die Tabelle Recht enthält sämtliche Berechtigungen (derzeit 10, können mehr werden). Tabelle Benutzer enthält sämtliche Benutzer. Und BenutzerRecht enthält, welcher Benutzer welches Recht hat.
Das große Problem: In BenutzerRecht habe ich nur Leute drinnen, die tatsächlich ein Recht haben. Neu angelegte Benutzer haben nämlich keinerlei Rechte. Außerdem speichere ich nur Rechte ab, die auch tatsächlich gegeben werden.
Folgende Tabellenstruktur:
mysql> describe Benutzer;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| ID | int(11) | | PRI | NULL | auto_increment |
| login | varchar(20) | | | | |
| vorname | varchar(20) | | | | |
| nachname | varchar(20) | | | | |
| password | varchar(50) | | | | |
+----------+-------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
mysql> select * from Benutzer;
+----+---------+---------------+---------------+----------------------------------+
| ID | login | vorname | nachname | password |
+----+---------+---------------+---------------+----------------------------------+
| 1 | rck | René | Kiesler | xxxxxxxxxxxxxxxx |
| 7 | admin | Administrator | darf alles | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| 6 | sammael | Florian | Schererbauer | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| 4 | demo | Demouser | Passwort=demo | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
+----+---------+---------------+---------------+----------------------------------+
4 rows in set (0.01 sec)
mysql> describe BenutzerRecht;
+------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+-------+
| BenutzerID | int(11) | | PRI | 0 | |
| RechtID | int(11) | | PRI | 0 | |
| darf | tinyint(1) | | | 0 | |
+------------+------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> select * from BenutzerRecht;
+------------+---------+------+
| BenutzerID | RechtID | darf |
+------------+---------+------+
| 1 | 3 | 2 |
| 4 | 2 | 1 |
| 1 | 2 | 1 |
| 7 | 1 | 3 |
| 7 | 2 | 3 |
| 7 | 3 | 3 |
| 7 | 4 | 3 |
| 7 | 5 | 3 |
| 7 | 6 | 3 |
| 7 | 7 | 3 |
| 7 | 8 | 3 |
| 7 | 9 | 3 |
| 7 | 10 | 3 |
+------------+---------+------+
13 rows in set (0.01 sec)
mysql> describe Recht;
+-------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+----------------+
| ID | int(11) | | PRI | NULL | auto_increment |
| bezeichnung | varchar(30) | | UNI | | |
+-------------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> select * from Recht;
+----+-------------------+
| ID | bezeichnung |
+----+-------------------+
| 1 | Benutzer |
| 2 | History |
| 3 | Branchen |
| 4 | Auftraggeber |
| 5 | Kunden |
| 6 | KundeAuftraggeber |
| 7 | Ablage |
| 8 | Stuetzpunkte |
| 9 | Tour |
| 10 | Entwicklung |
+----+-------------------+
10 rows in set (0.01 sec)
Alles anzeigen
und das Statement, mit dem ich das ganze verknüpfe (MySQL 4.1.0 mit Subselects ist aufgrund des Alpha-Status nicht erlaubt):
(SELECT Recht.ID, Recht.bezeichnung, Benutzer.login, 0 darf
FROM Recht LEFT JOIN BenutzerRecht BRR ON Recht.ID=BRR.RechtID,
BenutzerRecht BRL RIGHT JOIN Benutzer ON Benutzer.ID=BRL.BenutzerID
WHERE ((BRR.darf IS NULL) OR (BRL.darf IS NULL)))
UNION
(SELECT Recht.ID, Recht.bezeichnung, Benutzer.login, BRR.darf darf
FROM Recht LEFT JOIN BenutzerRecht BRR ON Recht.ID=BRR.RechtID,
BenutzerRecht BRL RIGHT JOIN Benutzer ON Benutzer.ID=BRL.BenutzerID
WHERE BRR.darf=BRL.darf)
UNION
(SELECT Recht.ID, Recht.bezeichnung, Benutzer.login, 0 darf
FROM Recht LEFT JOIN BenutzerRecht BRR ON Recht.ID=BRR.RechtID,
BenutzerRecht BRL RIGHT JOIN Benutzer ON Benutzer.ID=BRL.BenutzerID
WHERE AND BRR.darf!=BRL.darf)
ORDER BY Recht.bezeichnung;
Alles anzeigen
Die Lösung schaut nicht nur grauslich aus, sondern funktioniert auch nicht so ganz, wie sie soll. Man müsste über das ganze noch ein MAX(darf) machen, das geht aber irgendwie nicht und macht's auch nicht besser.
Ich werde das MAX(darf) mal händisch im PHP machen, nachdem ich auf keinen grünen Zweig komme. ...irgendwelche anderen Tips? // René