我将尝试向复杂的选择查询注入和数组数组
CREATE FUNCTION permission_cache_update(
IN affected_user_list INT4[]
)
RETURNS TABLE(user_id INT4, permission_id INT4)
AS
$BODY$
BEGIN
RETURN QUERY
WITH
affected_user AS (
SELECT unnest(affected_user_list) AS user_id
),
permission_summary AS
(
SELECT affected_user.user_id, role_permission.permission_id
FROM user_role, role_permission, affected_user
WHERE role_permission.role_id = user_role.role_id AND user_role.user_id = affected_user.user_id
UNION
SELECT affected_user.user_id, user_permission.permission_id
FROM user_permission, affected_user
WHERE user_permission.user_id = affected_user.user_id
)
SELECT user_id, permission_id
FROM permission_summary
GROUP BY user_id, permission_id;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
问题出在这一部分:
affected_user AS (
SELECT unnest(affected_user_list) AS user_id
),
但我不知道如何解决它。错误信息毫无意义。
[42601] ERROR: syntax error at or near "$2"
我想使用user_id, permission_id
对来更新包含相同值的权限缓存。因此,询问用户权限会更快,因为它们将被缓存在那里。我想使用db来存储和检查会话权限。我不知道这是否是明智的......
答案 0 :(得分:3)
我从你之前的问题中得出你正在使用PostgreSQL 8.4 ,这已经过时了。
您需要在每个问题中提供此信息!
在函数标题中声明
RETURNS TABLE(user_id INT4, permission_id INT4)
{/ 1}}参数OUT
和user_id
在PL / pgSQL的函数体中随处可见。为避免命名冲突,您需要对同名的列进行表限定。您的函数也无法与现代Postgres一起正常工作,因为最终permission_id
中的引用将返回SELECT
值:
NULL
Postgres 8.4有更多的问题和
的错误SELECT user_id, permission_id
命名冲突对于旧版本是不可接受的。较新的版本解决了这个问题。
您可以将 SQL函数与大致简化的查询一起使用:
SELECT unnest(affected_user_list) AS user_id
使用正确的连接语法。更容易阅读和维护。
我还简化了CREATE FUNCTION permission_cache_update(affected_user_list int[])
RETURNS TABLE(user_id int, permission_id int) AS
$func$
WITH affected_user AS (SELECT unnest($1) AS user_id)
SELECT a.user_id, r.permission_id
FROM user_role u
JOIN role_permission r USING (role_id)
JOIN affected_user a USING (user_id)
UNION
SELECT a.user_id, p.permission_id
FROM user_permission p
JOIN affected_user a USING (user_id)
$func$ LANGUAGE sql;
,这是品味和风格的问题。它更简单,更短,但需要明确的列名。因此,对于Postgres 8.4的plpgsql版本也不行,但在现代版本中有效。
原始查询中包含USING
的最终SELECT
只是噪音。
GROUP BY
(与UNION
相对)已隐式删除重复项。
如果避免命名冲突,plpgsql版本也应该起作用:
UNION ALL
答案 1 :(得分:2)
您确定问题与您引用的部分有关吗?我刚刚创建了该函数的简化版本并且它可以工作。您尝试使用什么版本的Postgres?也许某些功能在您的版本中不起作用(我在9.2上测试过)。
我测试了什么:
DROP FUNCTION IF EXISTS permission_cache_update(int4[]);
CREATE FUNCTION permission_cache_update(
IN affected_user_list INT4[]
)
RETURNS TABLE(user_id INT4, user_id2 INT4)
AS
$BODY$
BEGIN
RETURN QUERY
WITH
affected_user AS (
SELECT unnest(affected_user_list) AS user_id
),
foo as (select * from affected_user)
select au.*, foo.*
from affected_user au
inner join foo using (user_id);
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
select * from permission_cache_update(array[1,2,3]::int4[]);
user_id | user_id2
---------+----------
1 | 1
2 | 2
3 | 3