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。我没有尝试交叉连接,这可能是一个不错的方法