Пожалуйста, рассмотрите следующую (рабочую) хранимую процедуру.Эта функция получает целое число в качестве первого параметра, указывающего, какой privilegeid
должен быть проверен у текущего пользователя.Привилегии хранятся в таблице privileges
и состоят из идентификатора и имени (varchar).
Каждая привилегия принадлежит одному или нескольким roles
, хранящимся в users_roles
.Каждому пользователю назначается одна или несколько ролей.Эта функция извлекает все роли, назначенные current_user
, и проверяет их, как сказано, по заданному привилигеиду.
CREATE OR REPLACE FUNCTION "public"."has_privilege" (in int4) RETURNS bool AS
$BODY$
DECLARE
asked_privilegeid ALIAS FOR $1;
userid int;
role_row users_roles%rowtype;
privilege_row privileges%rowtype;
BEGIN
EXECUTE 'SELECT userid FROM users WHERE username=$1' INTO userid USING current_user;
FOR role_row IN SELECT * FROM users_roles
WHERE userid=userid
LOOP
IF role_row.roleid = 1 THEN
return TRUE;
END IF;
FOR privilege_row IN SELECT * FROM privileges WHERE roleid=role_row.roleid LOOP
IF privilege_row.privilegeid = asked_privilegeid THEN
return TRUE;
END IF;
END LOOP;
END LOOP;
return FALSE;
END
$BODY$
LANGUAGE 'plpgsql'
Однако этот код неэффективен, так как он может учитывать, что извлекает все значения строк для users_roles
и privileges
.Я попытался написать процедуру следующим образом, но она не работает:
CREATE OR REPLACE FUNCTION "public"."has_privilege" (in int4) RETURNS bool AS
$BODY$
DECLARE
asked_privilegeid ALIAS FOR $1;
privilegeid int;
userid int;
roleid int;
//role_row users_roles%rowtype;
//privilege_row privileges%rowtype;
BEGIN
EXECUTE 'SELECT userid FROM users WHERE username=$1' INTO userid USING current_user;
FOR roleid IN SELECT roleid FROM users_roles
WHERE userid=userid
LOOP
IF roleid = 1 THEN
return TRUE;
END IF;
FOR privilegeid IN SELECT privilegeid FROM privileges WHERE roleid=roleid LOOP
IF privilegeid = asked_privilegeid THEN
return TRUE;
END IF;
END LOOP;
END LOOP;
return FALSE;
END
$BODY$
LANGUAGE 'plpgsql'
Что я делаю не так?Заранее спасибо!
Редактировать : отступы не были выполнены, как ожидалось.Вот ссылки для вставки: http://pastebin.com/w18WaCW0 http://pastebin.com/W8ewXxEe