[英]Reusing variables in PGSQL queries
我有一个查询,将其简化为:
WITH users AS (
SELECT member_id FROM group_members AS gm
JOIN groups AS g on gm.group_id = g.id
WHERE g.id = 1337 OR g.parents @> ARRAY[1337]
)
UPDATE access SET revoked = TRUE
WHERE user_id IN (SELECT member_id FROM users)
RETURNING user_id;
这可行,但是我必须多次输入该id值(1337)。 在我的抽象示例中,这并不是很糟糕,但是对于更复杂的现实世界查询而言,这确实很丑陋,而且由于我使用的是PHP / PDO,因此必须多次传递相同的变量。
我要寻找的是一些技巧,一次声明我的变量,然后重用它,例如:
DECLARE gid = 1337
WITH users AS (
SELECT member_id FROM group_members AS gm
JOIN groups AS g on gm.group_id = g.id
WHERE g.id = gid OR g.parents @> ARRAY[gid]
)
UPDATE access SET revoked = TRUE
WHERE user_id IN (SELECT member_id FROM users)
RETURNING user_id;
但显然这行不通。
有没有一种方法可以在pgsql查询中声明一次变量并重用它?
with gid as (
select 1337 as gid
), users as (
select member_id
from
group_members as gm
join
groups as g on gm.group_id = g.id
where
g.id = (select gid from gid) or
g.parents @> array[(select gid from gid)]
)
update access
set revoked = true
where user_id in (select member_id from users)
或如果子查询太丑则进行交叉联接
with gid as (
select 1337 as gid
), users as (
select member_id
from
group_members as gm
join
groups as g on gm.group_id = g.id
cross join
gid
where g.id = gid or g.parents @> array[gid]
)
update access
set revoked = true
where user_id in (select member_id from users)
但是,如果您要从PHP传递参数,那么我看不到仅将参数持有人放在1337
不幸的是,这不是一个好方法。 Clodaldo展示了在普通SQL中真正可行的唯一方法。
另一种方法(通常是我做的)是将其包装在一个简单的SQL函数中。
CREATE OR REPLACE FUNCTION do_whatever(gid integer) RETURNS SETOF integer AS $$
WITH users AS (
SELECT member_id FROM group_members AS gm
JOIN groups AS g on gm.group_id = g.id
WHERE g.id = $1 OR g.parents @> ARRAY[$1]
)
UPDATE access SET revoked = TRUE
WHERE user_id IN (SELECT member_id FROM users)
RETURNING user_id;
$$ LANGUAGE sql;
SELECT * FROM do_whatever(1337);
不幸的是PostgreSQL没有TEMPORARY
函数, DO
块不能接受参数或返回行集。 因此,这不是理想的方法,但是可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.