Php 在PGSQL查询中重用变量
我有一个查询,我将其简化为:Php 在PGSQL查询中重用变量,php,postgresql,pdo,Php,Postgresql,Pdo,我有一个查询,我将其简化为: 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 (SELEC
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
或者,如果子查询太难看,则执行交叉连接
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没有
临时
函数,DO
块不能获取参数或返回行集。因此,这并不理想,但很有效。不幸的是,没有一个好方法。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没有
临时
函数,DO
块不能获取参数或返回行集。所以这并不理想,但它可以工作。在PDO中,您只能使用一次参数,因此我必须多次通过1337。我没有尝试交叉连接,这在PDO中可能是一种不错的方法,您只能使用一次参数,因此我必须多次通过1337。我没有尝试交叉连接,这可能是一个不错的方法