【问题标题】:postgres initializing a variable in a do blockpostgres在do块中初始化变量
【发布时间】:2021-03-16 14:34:48
【问题描述】:

在 Postgres 的 do 块中的一个非常基本的级别上,我想调用一个函数并获取值并进行必要的更新 - 但看起来我第一次从块中调用函数时它被初始化并且不更新随后。

我已经尝试分解块并有子块 - 没有运气。下面是一个非常简单的例子:

do $$
<<outer_block>>
declare
    _counter int := 0 ;
begin
    while _counter < 5
        loop
            declare _now timestamp := getTime(); --now();
            begin
                raise notice 'COUNTER : % TIME STAMP : %' , _counter, _now;
            end;
            _counter := _counter + 1;
            perform pg_sleep(5);
        end loop;
end outer_block $$;

getTime 是 ...

create or replace function getTime() returns timestamp   --setof record 
language plpgsql
as 
$$
declare
    _val timestamp := now();
begin
--  _val := now();
    return _val;
end $$;

主块的输出是相同的时间戳。

是不是因为 Postgres 而不是顺序发送整个块作为一个对象,所以时间戳是一样的?

我可以在函数中添加一个插入到临时表并让触发器更新另一个表以获取时间戳(或新的初始化值?)

主块的输出是:

NOTICE:  COUNTER : 0 TIME STAMP : 2021-03-15 19:03:07.73432
NOTICE:  2021-03-15 19:03:07.73432-04
NOTICE:  COUNTER : 1 TIME STAMP : 2021-03-15 19:03:07.73432
NOTICE:  2021-03-15 19:03:07.73432-04
NOTICE:  COUNTER : 2 TIME STAMP : 2021-03-15 19:03:07.73432
NOTICE:  2021-03-15 19:03:07.73432-04
NOTICE:  COUNTER : 3 TIME STAMP : 2021-03-15 19:03:07.73432
NOTICE:  2021-03-15 19:03:07.73432-04
NOTICE:  COUNTER : 4 TIME STAMP : 2021-03-15 19:03:07.73432
NOTICE:  2021-03-15 19:03:07.73432-04
DO

【问题讨论】:

    标签: postgresql function block plpgsql


    【解决方案1】:

    基于Postgres now() timestamp doesn't change, when script works,可以试试timeofday()代替now()

    edb=# create or replace function getTime() returns timestamp   --setof record 
    language plpgsql
    as 
    $$                     
    declare
        _val timestamp := timeofday();
    begin
    --  _val := timeofday();
        return _val;
    end $$ volatile;
    CREATE FUNCTION
    edb=# do $$                                                                   
    <<outer_block>>
    declare
        _counter int := 0 ;
    begin
        while _counter < 5
            loop
                declare _now timestamp := getTime(); --now();
                begin
                    raise notice 'COUNTER : % TIME STAMP : %' , _counter, _now;
                end;
                _counter := _counter + 1;
                perform pg_sleep(5);
            end loop;
    end outer_block $$;
    NOTICE:  COUNTER : 0 TIME STAMP : 15-MAR-21 23:44:17.870405
    NOTICE:  COUNTER : 1 TIME STAMP : 15-MAR-21 23:44:22.875366
    NOTICE:  COUNTER : 2 TIME STAMP : 15-MAR-21 23:44:27.880828
    NOTICE:  COUNTER : 3 TIME STAMP : 15-MAR-21 23:44:32.886212
    NOTICE:  COUNTER : 4 TIME STAMP : 15-MAR-21 23:44:37.891187
    DO
    

    【讨论】:

    • 我会推荐 clock_timestamp() 而不是将时间戳转换为 text 并返回。
    • 非常感谢!我非常感谢您的回复 - 我一直试图循环执行此操作并尝试 now() - 但谢谢。
    猜你喜欢
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多