【问题标题】:How do I update multiple records at a time from a subselect inPL/pgSQL如何从子选择 inPL/pgSQL 一次更新多条记录
【发布时间】:2013-07-02 03:11:39
【问题描述】:

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

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

现在我正在使用循环来获取单行并更新它,使用返回存储结果,这有效但速度很慢。

建议?

这是当前的工作版本以及架构创建语句。

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;

【问题讨论】:

  • 这看起来是可写公用表表达式 (wCTE) 的理想选择。顺便说一下,它是 PL/PgSQL; PostgreSQL 不支持 Oracle 过程语言 PL/SQL。

标签: postgresql stored-procedures postgresql-9.1 plpgsql


【解决方案1】:

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

创建或替换函数 public.fx2(n 整数) 返回设置 oo 语言 plpgsql 作为$函数$ 开始 返回查询更新 oo 设置 a = b b 在哪里(选择 b 来自oo 按 b 订购 限制 n) 返回 *; 返回; 结尾; $函数$ postgres=# insert into oo select 1, i from generate_series(1,100) g(i); 插入 0 100 postgres=# select * from fx2(1); 一个 | b ---+--- 1 | 1 (1 行) postgres=# select * from fx2(4); 一个 | b ---+--- 1 | 1 2 | 2 3 | 3 4 | 4 (4 行) postgres=# select * from oo limit 10; 一个 | b ---+---- 1 | 5 1 | 6 1 | 7 1 | 8 1 | 9 1 | 10 1 | 11 1 | 12 1 | 13 1 | 14 (10 行)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    相关资源
    最近更新 更多