plpgsql cte参数化与数组原因错误消息
我将尝试向一个复杂的select查询注入和数组IDplpgsql cte参数化与数组原因错误消息,sql,postgresql,plpgsql,postgresql-8.4,Sql,Postgresql,Plpgsql,Postgresql 8.4,我将尝试向一个复杂的select查询注入和数组ID 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_us
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
),
但我不知道如何修复它。错误消息没有意义
我想使用
user\u id,permission\u id
对更新包含相同值的权限缓存。因此,询问用户权限会更快,因为它们将被缓存在那里。我想使用db来存储和检查会话权限。我不知道这是否明智…你确定问题出在你引用的章节上吗?我刚刚创建了该函数的简化版本,它可以正常工作。你在试用什么版本的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
你确定问题出在你引用的章节上吗?我刚刚创建了该函数的简化版本,它可以正常工作。你在试用什么版本的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
我从您前面的问题中得出结论,您使用的是PostgreSQL8.4,现在已经非常过时了。
您需要在每个问题中提供此信息 在函数头中声明
RETURNS TABLE(user_id INT4, permission_id INT4)
PL/pgSQL中的函数体中随处可见OUT
参数user\u id
和permission\u id
。为了避免命名冲突,您需要对相同名称的列进行表限定。您的函数也无法在现代Postgres中正常工作,因为您的最终SELECT
中的引用将返回NULL
值:
SELECT user_id, permission_id
Postgres 8.4在这方面有更多的问题,并且在
SELECT unnest(affected_user_list) AS user_id
- 使用正确的连接语法。更容易阅读和维护。
我还使用简化了
,这是一个品味和风格的问题。它更简单、更短,但需要明确的列名。因此,这在Postgres 8.4的plpgsql版本中也不起作用,但在现代版本中起作用
- 原始查询中带有
分组依据的最后一个
,就是噪音。选择
(与UNION
相反)已隐式删除重复项UNION ALL
CREATE FUNCTION permission_cache_update(affected_user_list int[])
RETURNS TABLE(user_id int, permission_id int) AS
$func$
BEGIN
RETURN QUERY
WITH affected_user AS (
SELECT unnest(affected_user_list) AS u_id
)
SELECT a.user_id, r.permission_id
FROM user_role u
JOIN role_permission r USING (role_id)
JOIN affected_user a ON a.u_id = u.user_id
UNION
SELECT a.user_id, p.permission_id
FROM user_permission p
JOIN affected_user a ON a.u_id = p.user_id;
END
$func$ LANGUAGE plpgsql;
我从您前面的问题中得出结论,您使用的是PostgreSQL8.4,现在已经非常过时了。
您需要在每个问题中提供此信息 在函数头中声明
RETURNS TABLE(user_id INT4, permission_id INT4)
PL/pgSQL中的函数体中随处可见OUT
参数user\u id
和permission\u id
。为了避免命名冲突,您需要对相同名称的列进行表限定。您的函数也无法在现代Postgres中正常工作,因为您的最终SELECT
中的引用将返回NULL
值:
SELECT user_id, permission_id
Postgres 8.4在这方面有更多的问题,并且在
SELECT unnest(affected_user_list) AS user_id
- 使用正确的连接语法。更容易阅读和维护。
我还使用简化了
,这是一个品味和风格的问题。它更简单、更短,但需要明确的列名。因此,这在Postgres 8.4的plpgsql版本中也不起作用,但在现代版本中起作用
- 原始查询中带有
分组依据的最后一个
,就是噪音。选择
(与UNION
相反)已隐式删除重复项UNION ALL
CREATE FUNCTION permission_cache_update(affected_user_list int[])
RETURNS TABLE(user_id int, permission_id int) AS
$func$
BEGIN
RETURN QUERY
WITH affected_user AS (
SELECT unnest(affected_user_list) AS u_id
)
SELECT a.user_id, r.permission_id
FROM user_role u
JOIN role_permission r USING (role_id)
JOIN affected_user a ON a.u_id = u.user_id
UNION
SELECT a.user_id, p.permission_id
FROM user_permission p
JOIN affected_user a ON a.u_id = p.user_id;
END
$func$ LANGUAGE plpgsql;
我给博士后加上了8.4的标签,这是一个有根据的猜测。如果不是这样,请修改。下次请记得马上提供你的版本。它是8.4,很抱歉我忘了提到。我标记了Postgres 8.4,这是一个有根据的猜测。如果不是这样,请修改。下次请记得马上提供你的版本。它是8.4,很抱歉我忘了提到。我想你的猜测是对的。错误可以在Postgres 8.4中重现。是的,版本是8.4。我想你的猜测是对的。错误可以在Postgres 8.4.Yepp中重现,版本是8.4Nice,捕捉命名冲突!是的,问题是名称重复,它不能使用相同的名称…很好地抓住了命名冲突!是的,问题是名称重复,它不能使用相同的名称。。。