如何在 postgres 函数中设置时区

How to set timezone inside a postgres function

CREATE OR REPLACE FUNCTION myfunction(userid BIGINT)
  RETURNS REAL
  SECURITY DEFINER
LANGUAGE plpgsql
AS $$
DECLARE
  ------------------------Fetch all Active Games for a user and add it to one cursor--------------------------------------
    PersonGames NO SCROLL CURSOR FOR select timezonename from user where id=userid;
BEGIN
  OPEN PersonGames;
  LOOP

    FETCH PersonGames INTO PersonGame;
    IF NOT found
    THEN
      EXIT;
    END IF;
    SET TIMEZONE=PersonGame.timezonename;
  --  execute 'set TIMEZONE=' using PersonGame.timezonename;
end loop;
END;
$$;

我得到参数 "TimeZone" 的错误值无效:"timezonename"

我什至尝试使用 PersonGame.timezonename;

更改代码执行 'set TIMEZONE='

但这也行不通。

我想在我的函数中设置时区。

非常感谢任何帮助。

谢谢

您可以通过两种不同的方式进行:

  1. 您可以使用 EXECUTE command, with a fully-constructed string (i.e.: without USING1), and use the SET [LOCAL] TIME ZONE 语句,就像您在函数中所做的那样。

    这个函数让你测试一下:

    CREATE OR REPLACE FUNCTION test_set_time_zone(_new_time_zone TEXT)
       RETURNS TEXT
       SECURITY DEFINER
       LANGUAGE plpgsql
    AS $$
    BEGIN
        EXECUTE 'SET LOCAL TIME ZONE ''' || _new_time_zone || ''';' ;
        RETURN current_setting('timezone')  ;
    END;
    $$;
    

    您可以通过以下方式查看:

    SELECT test_set_time_zone('Europe/Paris');
    
    | test_set_time_zone |
    | :----------------- |
    | Europe/Paris       |
    
  2. 可以使用set_config() function in a similar fashion, being called via PERFORM,设置'timezone'作为参数进行配置,并决定设置local还是global .

    您可以通过以下方式查看:

    CREATE OR REPLACE FUNCTION test_set_time_zone_2 (_new_time_zone TEXT)
       RETURNS TEXT
       SECURITY DEFINER
       LANGUAGE plpgsql
    AS $$
    BEGIN
        PERFORM set_config('timezone', _new_time_zone, true /* local */) ;
        RETURN current_setting('timezone')  ;
    END;
    $$;
    
    SELECT test_set_time_zone_2('US/Central') ;
    
    | test_set_time_zone_2 |
    | :------------------- |
    | US/Central           |
    

你可以在 dbfiddle 查看这两个函数 here 我没有尝试任何全局设置,因为我猜在这个平台上网络用户不会拥有适当的特权;我最好的猜测是你可以在你的系统中做全局的改变,做同样的事情。


1) 根据 Pavel Stehule 的评论:USING 子句可用于执行计划仅参数。 SET 没有执行计划 - 然后 USING 子句不可用。