2016-06-23 6 views
-1

Ich habe eine Abfrage, wo ich überprüfen, der Benutzer hat alle Berechtigungen in einer Liste von Dauerwellen vorhanden.Übergeben Sie eine Liste in MySQL gespeicherte Prozedur und überprüfen Sie alle Werte sind

Also, es ist so etwas wie dieses ...

SELECT DISTINCT account_id 
FROM pp_acl_user_roles ur, pp_acl_role_permissions rp 
JOIN pp_acl_permissions p ON rp.permission_id=p.id 
WHERE (
    ur.account_id = '1' 
    #check for permission ids OR keys depending on what has been passed in. 
    AND (p.id IN ('read_accounts', 'write_accounts') OR p.key IN ('read_accounts', 'write_accounts')) 
    AND ur.role_id = rp.role_id 
) 
#ensure we have ALL the permissions we asked for, not just some -makes IN() an AND not an OR. 
GROUP BY ur.account_id 
HAVING COUNT(DISTINCT rp.permission_id) = 2 

Es ist für prüft entweder eine Liste von id s oder eine Liste von keys für die Berechtigungen, so könnte es mit entweder aufgerufen werden, so dass diese Linie.

p.id IN ('read_accounts', 'write_accounts') OR p.key IN ('read_accounts', 'write_accounts') 

konnte

p.id IN (1, 2) OR p.key IN (1, 2) 

sein, je nachdem, wie es genannt wird.

Die HAVING am Ende stellt sicher, dass wir alle die Artikel, die wir gefragt haben.

Das ist in Ordnung, aber ich möchte es in eine gespeicherte Prozedur verschieben, und ich bin ein Problem.

hatte ich IN für FIND_IN_SET so zu ändern, die ich eine Stringliste in das Verfahren passieren könnte, aber das Problem ist, dass ich keine Möglichkeit habe, zu dynamisch zu berechnen, wie viele Elemente in der Liste sind, so kann ich nicht überprüfen Sie sind alle anwesend.

Iv'e hätte dies bisher ...

CREATE PROCEDURE has_permission(IN account_id BIGINT, IN permissions TEXT) 
BEGIN 
    SELECT DISTINCT account_id 
    FROM pp_acl_user_roles ur, pp_acl_role_permissions rp 
    JOIN pp_acl_permissions p ON rp.permission_id=p.id 
    WHERE (
    ur.account_id = account_id 
    #check for permission ids OR keys depending on what has been passed in. 
    AND (FIND_IN_SET(p.id, permissions) OR FIND_IN_SET(p.key, permissions)) 
    AND ur.role_id = rp.role_id 
) 
    #ensure we have ALL the permissions we asked for, not just some -makes IN() an AND not an OR. 
    GROUP BY ur.account_id; 
    HAVING COUNT(DISTINCT rp.permission_id) = ???????????? 
END //      
DELIMITER ; 

Aber es gibt keine Möglichkeit, die Länge der Berechtigungen in geben zu berechnen.

Ich bin sicher, dass es eine Möglichkeit, vielleicht ist JOIN zu der perms-Tabelle basierend auf den Elementen in der Zeichenfolge und sicherstellen, dass wir Übereinstimmungen in beiden Tabellen haben, aber ich kann es nicht ausarbeiten.

Alle Zeiger sehr geschätzt ...

+0

ist es ausreichend für Ihr Frontend, eine Zeichenkette wie '(1,2,3)' zu übergeben und für den gespeicherten Proc festzustellen, ob es mindestens 1 gibt, die * nicht * in dieser Liste von Dauerwellen ist? – Drew

+0

Ja, wenn einer der übergebenen Dauerwellen nicht diesem Benutzer zugewiesen ist, der funktionieren würde .... –

Antwort

0

Das ist, was ich bisher ...

Nicht ideal habe, aber Sie können mit diesem die Länge der Elemente in der Zeichenfolge trainieren.

.
(SELECT LENGTH(permissions) - LENGTH(REPLACE(permissions, ',', '')) + 1) 

Es zählt im Grunde alle Kommas in der Zeichenfolge und verwendet diese als die Gesamtzahl der perms in geben.

CREATE PROCEDURE has_permission(IN account_id BIGINT, IN permissions TEXT) 
BEGIN 
    SELECT DISTINCT account_id 
    FROM pp_acl_user_roles ur, pp_acl_role_permissions rp 
    JOIN pp_acl_permissions p ON rp.permission_id=p.id 
    WHERE (
    ur.account_id = account_id 
    #check for permission ids OR keys depending on what has been passed in. 
    AND (FIND_IN_SET(p.id, permissions) OR FIND_IN_SET(p.key, permissions)) 
    AND ur.role_id = rp.role_id 

) 
    #ensure we have ALL the permissions we asked for, not just some -makes IN() an AND not an OR. 
    GROUP BY ur.account_id 
    HAVING COUNT(DISTINCT rp.permission_id) = (SELECT LENGTH(permissions) - LENGTH(REPLACE(permissions, ',', '')) + 1); 
Verwandte Themen