【问题标题】:How to set timezone inside a postgres function如何在 postgres 函数中设置时区
【发布时间】:2017-07-16 07:32:23
【问题描述】:
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=$1' using PersonGame.timezonename;
end loop;
END;
$$;

我收到参数“TimeZone”的错误无效值:“timezonename”

即使我尝试使用 PersonGame.timezonename 更改代码执行 'set TIMEZONE=$1';

但这也行不通。

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

非常感谢任何帮助。

谢谢

【问题讨论】:

  • 1.为什么要更改 Postgres DB 时区?此设置适用于整个数据库。 2、语法为SET TIME ZONE valuesee documentation)。
  • 我有一个要求,这需要用户明智。我已经尝试过但无法正常工作。
  • @KristoMägi:通过set 更改时区不适用于“整个数据库” - 仅适用于当前会话。

标签: postgresql function stored-procedures plpgsql


【解决方案1】:

您可以通过两种不同的方式做到这一点:

  1. 您可以使用EXECUTE 命令,使用完全构造的字符串(即:没有USING1),并使用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 | | :----------------- | |欧洲/巴黎 |
  2. 您可以通过类似的方式使用set_config()函数,通过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 | | :-------------------- | |美国/中部 |

您可以在 dbfiddle here 上查看这两个功能我最好的猜测是,您可以在系统中进行全局更改,并执行相同的操作。


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

【讨论】:

  • USING 子句仅可用于执行计划参数。 SET 没有执行计划 - 然后USING 子句不可用。
  • 是的,第二部分使用 PERFORM 'SET TIME ZONE '||TimezoneName;
  • 为什么 postgres 在这里需要字符串文字?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
相关资源
最近更新 更多