我有以下的 - 不工作 - 功能:plgpsql - 是否可以聲明setof記錄或表變量?
CREATE FUNCTION permission_cache_update(affected_user_list int[])
RETURNS TABLE(user_id INT4, permission_id INT4)
AS
$BODY$
DECLARE
current_relations SETOF RECORD;
BEGIN
WITH
affected_user AS (
SELECT unnest(affected_user_list) AS u_id
),
affected_relations AS (
SELECT user_role.user_id, role_permission.permission_id
FROM user_role
JOIN role_permission ON user_role.role_id = role_permission.role_id
JOIN affected_user ON affected_user.u_id = user_role.user_id
UNION
SELECT user_permission.user_id, user_permission.permission_id
FROM user_permission
JOIN affected_user ON affected_user.u_id = user_permission.user_id
)
SELECT affected_relations.user_id, affected_relations.permission_id FROM affected_relations
INTO current_relations;
DELETE FROM permission_cache WHERE ARRAY[user_id] <@ affected_user_list;
INSERT INTO permission_cache (user_id, permission_id) SELECT user_id, permission_id FROM current_relations;
END
$BODY$
LANGUAGE plpgsql;
我想將當前用戶的權限關係,current_relations
存儲爲(INT4,INT4)。是否有可能做到這一點與變量沒有循環和臨時表?
我會用這樣的事情以後,所以我真的需要它作爲變量,而不是子查詢
DELETE FROM permission_cache WHERE ARRAY[user_id] <@ affected_user_list AND NOT IN (SELECT user_id, permission_id FROM current_relations);
INSERT INTO permission_cache (user_id, permission_id) SELECT user_id, permission_id FROM current_relations WHERE NOT EXIST (SELECT user_id, permission_id FROM permission_cache);
我認爲這是可能的表 - >二維數組轉換,但這是複雜的,因此,如果它可能與記錄,它會更好...
解決方案:
這是比較容易創建一維數組,而不是使用記錄或二維數組循環:
CREATE FUNCTION permission_cache_update(
IN affected_user_list INT4 []
)
RETURNS VOID
AS
$BODY$
DECLARE
user_index INT4;
current_user_id INT4;
current_permission_relations INT4 [];
deleted_permission_relations INT4 [];
inserted_permission_relations INT4 [];
BEGIN
FOR user_index IN 1 .. array_upper(affected_user_list, 1) LOOP
current_user_id := affected_user_list[user_index];
WITH
user_permission_summary AS
(
SELECT
role_permission.permission_id
FROM user_role, role_permission
WHERE role_permission.role_id = user_role.role_id AND user_role.user_id = current_user_id
UNION
SELECT
user_permission.permission_id
FROM user_permission
WHERE user_permission.user_id = current_user_id
)
SELECT
array_agg(permission_id)
FROM user_permission_summary
INTO current_permission_relations;
SELECT
array_agg(permission_cache.permission_id)
FROM permission_cache
WHERE permission_cache.user_id = current_user_id AND (current_permission_relations IS NULL OR
NOT (ARRAY [permission_cache.permission_id] <@ current_permission_relations))
INTO deleted_permission_relations;
SELECT
array_agg(inserted_permission_id)
FROM unnest(current_permission_relations) AS inserted_permission_id
WHERE NOT EXISTS(SELECT
1
FROM permission_cache
WHERE permission_cache.user_id = current_user_id AND
permission_cache.permission_id = inserted_permission_id)
INTO inserted_permission_relations;
DELETE FROM permission_cache
WHERE permission_cache.user_id = current_user_id AND
permission_cache.permission_id = ANY (deleted_permission_relations);
INSERT INTO permission_cache (user_id, permission_id)
SELECT
current_user_id,
inserted_permission_id
FROM unnest(inserted_permission_relations) AS inserted_permission_id;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
關: Pplpgsql是一個更差勁的文檔一個非常貧窮的語言,我不喜歡它... 很抱歉的代碼格式,套用在我的IDE也不是那麼好...:S
您仍然聲明:'RETURNS TABLE(user_id INT4,permission_id INT4)'。這是一個神器還是你真的想要另外返回行? –
Ohh no:D它只是以前代碼的一部分... – inf3rno