Postgresql 如何从子选择inPL/pgSQL一次更新多条记录

Postgresql 如何从子选择inPL/pgSQL一次更新多条记录,postgresql,stored-procedures,postgresql-9.1,plpgsql,Postgresql,Stored Procedures,Postgresql 9.1,Plpgsql,我有一个存储过程,它可以工作,但速度非常慢 基本上,我想做的是在单个update命令中更新从子查询中获得的一组行。另一个警告是,我想返回我在语句中更新的行 现在我正在使用一个循环来获取一行并更新它,使用returning-to存储结果,这虽然有效,但速度非常慢 建议 以下是当前工作版本以及模式创建语句 CREATE TABLE "queued_message" ( id bigserial NOT NULL, body json NOT NULL, status character

我有一个存储过程,它可以工作,但速度非常慢

基本上,我想做的是在单个update命令中更新从子查询中获得的一组行。另一个警告是,我想返回我在语句中更新的行

现在我正在使用一个循环来获取一行并更新它,使用returning-to存储结果,这虽然有效,但速度非常慢

建议

以下是当前工作版本以及模式创建语句

CREATE TABLE "queued_message"
(
  id bigserial NOT NULL,
  body json NOT NULL,
  status character varying(50) NOT NULL,
  queue character varying(150) NOT NULL,
  last_modified timestamp without time zone NOT NULL,
  CONSTRAINT id_pkey PRIMARY KEY (id)
);

CREATE TYPE returned_message as (id bigint, body json, status character varying(50) , queue character varying(150), last_modified timestamp without time zone);

CREATE OR REPLACE FUNCTION get_next_notification_message_batch(desiredQueue character varying(150), numberOfItems integer) 
    RETURNS SETOF returned_message AS $$ 
    DECLARE result returned_message; messageCount integer := 1;
    BEGIN
    lock table queued_notification_message in exclusive mode;
    LOOP 
        update queued_notification_message
        set 
            status='IN_PROGRESS', last_modified=now()
        where
            id in (
            select
                id
            from
                queued_notification_message
            where
                status='SUBMITTED' and queue=desiredQueue
            limit 1
            )
        returning * into result;
        RETURN NEXT result; 
        messageCount := messageCount+1;
        EXIT WHEN messageCount > numberOfItems;
    END LOOP;   
END;$$LANGUAGE plpgsql;

代码很难加速,因为UPDATE语句的LIMIT子句不受支持,这将是相同的,也许下面的示例就足够了:

CREATE OR REPLACE FUNCTION public.fx2(n integer) RETURNS SETOF oo LANGUAGE plpgsql AS $function$ begin return query update oo set a = b where b in (select b from oo order by b limit n) returning *; return; end; $function$ postgres=# insert into oo select 1, i from generate_series(1,100) g(i); INSERT 0 100 postgres=# select * from fx2(1); a | b ---+--- 1 | 1 (1 row) postgres=# select * from fx2(4); a | b ---+--- 1 | 1 2 | 2 3 | 3 4 | 4 (4 rows) postgres=# select * from oo limit 10; a | b ---+---- 1 | 5 1 | 6 1 | 7 1 | 8 1 | 9 1 | 10 1 | 11 1 | 12 1 | 13 1 | 14 (10 rows)
这看起来是一个很好的可写公共表表达式wCTE候选。顺便说一下,它是PL/PgSQL;PostgreSQL不支持Oracle过程语言PL/SQL。