相关疑难解决方法(0)

在 PL/pgSQL 中调用另一个函数内的函数

我定义了一个函数来总是给我下一个星期天的日期。它工作正常,这是代码:

CREATE FUNCTION nextSunday() RETURNS date AS $$
DECLARE
    dia_semana INT := CAST(EXTRACT(DOW FROM CURRENT_DATE)as INT);
    dia INT :=  7 - dia_semana;
BEGIN
    RETURN current_date + dia;
END;
$$ LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)

我有另一个函数可以将数据转储到文件中,我需要在nextSunday()里面使用函数:

CREATE OR REPLACE FUNCTION popularTabelaPessoa() RETURNS VOID AS $$
BEGIN
COPY(SELECT pe.id, pe.fk_naturalidade, pe.fk_documentacao_pessoal, pe.nome, 
       pe.cpf, pe.data_nascimento, pe.sexo, pe.estado_civil, pe.nome_mae,
       pe.data_alteracao, pe.usuario_banco_alteracao,
       pe.usuario_aplicacao_alteracao
FROM fluxo_lt.banca ba
INNER JOIN corporativo.localidade lo
    ON ba.fk_municipio = lo.id
INNER JOIN fluxo_lt.agendamento_candidato ac
    ON ac.fk_banca = ba.id
INNER JOIN info_detran.processo as …
Run Code Online (Sandbox Code Playgroud)

sql postgresql date plpgsql

8
推荐指数
1
解决办法
3万
查看次数

获取时区偏移的日期

我试图从postgres中的查询中提取日期.时间戳存储为UTC,所以如果我有1/1/2014 02:00:00,我希望太平洋时间的日期是12/31/2013,而不是2014年1月1日.我非常接近,但查询2和3仍然返回2014年1月1日.

SELECT '1-1-2014 02:00:00'::timestamp at time zone 'America/Los_Angeles';
Run Code Online (Sandbox Code Playgroud)

回报

2014-01-01 02:00:00-08
Run Code Online (Sandbox Code Playgroud)

-

SELECT CAST('1-1-2014 02:00:00'::timestamp at time zone 'America/Los_Angeles' AS Date);
Run Code Online (Sandbox Code Playgroud)

回报

2014-01-01
Run Code Online (Sandbox Code Playgroud)

但是我希望它能够回归2013-12-31.

SELECT CAST('1-1-2014 00:02:00'::timestamp at time zone 'America/Los_Angeles' AS Date) at time zone 'America/Los_Angeles';
Run Code Online (Sandbox Code Playgroud)

回报

2014-01-01 00:00:00
Run Code Online (Sandbox Code Playgroud)

但是我希望它能够回归 2013-12-31 00:00:00

我基本上想要在它所在的时区中返回日期,在这种情况下是太平洋时区.

postgresql timezone timestamp date

8
推荐指数
2
解决办法
2万
查看次数

应用于时间戳时,具有相同属性的时区名称会产生不同的结果

我只是花了一个小时绝望,这两个表达式的结果有差异:


db=# SELECT '2012-01-18 1:0 CET'::timestamptz AT TIME ZONE 'UTC'
           ,'2012-01-18 1:0 Europe/Vienna'::timestamptz AT TIME ZONE 'UTC';
      timezone       |      timezone
---------------------+---------------------
 2012-08-18 00:00:00 | 2012-08-17 23:00:00
Run Code Online (Sandbox Code Playgroud)

显然,第二个表达式根据DST规则扣除两个小时,其中第一个表达式仅使用标准偏移量.

我检查了这两个时区名称的目录.他们都在那里,看起来一样:

db=# SELECT * FROM pg_timezone_names WHERE name IN ('CET', 'Europe/Vienna');
     name      | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
 Europe/Vienna | CEST   | 02:00:00   | t
 CET           | CEST   | 02:00:00   | t
Run Code Online (Sandbox Code Playgroud)

我查阅了关于时区PostgreSQL手册:

PostgreSQL允许您以三种不同的形式指定时区:

全时区名称,例如America/New_York.识别的时区名称列在pg_timezone_names视图中(参见第45.67节).PostgreSQL为此目的使用广泛使用的zoneinfo时区数据,因此许多其他软件也识别相同的名称.

时区缩写,例如PST.这样的规范仅定义了与UTC的特定偏移,而不是全时区名称,其也可以暗示一组夏令时转换日期规则.公认的缩写列在pg_timezone_abbrevs视图中(参见第45.66节).您不能将配置参数timezone或log_timezone设置为时区缩写,但可以在日期/时间输入值和AT TIME ZONE运算符中使用缩写.

大胆的重点我的.

为什么差异呢?

我的设置(添加了更多细节)

  • 关于Debian …

postgresql timezone datetime

7
推荐指数
1
解决办法
2179
查看次数

复合键的每组行的序列号

我正在尝试维护一个地址历史表:

CREATE TABLE address_history (
    person_id int, 
    sequence int,
    timestamp datetime default current_timestamp,
    address text,
    original_address text,
    previous_address text,
    PRIMARY KEY(person_id, sequence),
    FOREIGN KEY(person_id) REFERENCES people.id
);
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一种简单的方法可以自动编号/约束sequence,address_history从而自动从1开始计数person_id.

换句话说,第一行person_id = 1会得到sequence = 1; person_id = 1会得到第二排sequence = 2.第一行person_id = 2,将sequence = 1再次获得.等等.
还有更好/内置的方式来维护这样的历史吗?

sql postgresql database-design auto-increment

7
推荐指数
1
解决办法
1913
查看次数

如何为Spring Boot JPA Timestamp指定UTC时区

环境

  • Spring Boot Starter Data JPA 1.4.2
  • Eclipselink 2.5.0
  • Postgresql 9.4.1211.jre7

问题

我正在构建一个Spring Boot微服务,它与不同的服务共享一个Postgresql数据库.数据库在外部初始化(在我们的控制之外),其他服务使用的日期时间列类型是没有时区的时间戳.因此,由于我希望db上的所有日期具有相同的类型,因此具有该类型是我的JPA实体日期的要求.

我在JPA实体对象上映射它们的方式如下:

@Column(name = "some_date", nullable = false)
private Timestamp someDate;
Run Code Online (Sandbox Code Playgroud)

问题是,当我按如下方式创建时间戳时:

new java.sql.Timestamp(System.currentTimeMillis())
Run Code Online (Sandbox Code Playgroud)

我查看数据库,时间戳包含我当地的时区日期时间,但我想将其存储在UTC中.这是因为我的默认时区设置为'Europe/Brussels',JPA/JDBC将我的java.sql.Timestamp对象转换为我的时区,然后再将其放入数据库.

找不到理想的解决方案

  • TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));具有我想要实现的效果,但它不适合,因为它不是特定于我的服务.即它会影响整个JVM或当前线程加上孩子.

  • 启动应用程序-Duser.timezone=GMT似乎也为正在运行的JVM的单个实例执行任务.因此,比前一个更好的解决方案.

但有没有办法在JPA/datasource/spring启动配置中指定时区?

java postgresql timezone jpa spring-boot

7
推荐指数
1
解决办法
1万
查看次数

将不带时区的时间戳转换为带时区的时间戳

我有一个类型为 nullable 的列timestamp without time zone。它以以下格式存储在我的 Postgres 数据库中:2021-06-24 11:00:00. 我想将其转换为可为空的timestamp with time zone类型,以便将其显示为2021-06-24 11:00:00.000-00. 请注意,没有时区转换。

该解决方案还应该允许从 转换timestamp with time zonetimestamp without time zone。我做了一些研究,但没有找到任何东西。

sql postgresql timestamp timestamp-with-timezone

7
推荐指数
2
解决办法
2万
查看次数

将日期时间约束添加到PostgreSQL多列部分索引

我有一个名为PostgreSQL的表queries_query,它有很多列.

其中两个列createduser_sid我的应用程序经常在SQL查询中一起使用,以确定给定用户在过去30天内完成了多少查询.在最近30天之前的任何时间查询这些统计数据是非常非常罕见的.

这是我的问题:

我目前通过运行以下方法在这两列上创建了我的多列索引:

CREATE INDEX CONCURRENTLY some_index_name ON queries_query (user_sid, created)
Run Code Online (Sandbox Code Playgroud)

但我想进一步限制索引只关心创建日期在过去30天内的查询.我尝试过以下方法:

CREATE INDEX CONCURRENTLY some_index_name ON queries_query (user_sid, created)
WHERE created >= NOW() - '30 days'::INTERVAL`
Run Code Online (Sandbox Code Playgroud)

但这引发了一个异常,说明我的函数必须是不可变的.

我很乐意让这个工作,以便我可以优化我的索引,并削减Postgres需要执行这些重复查询的资源.

postgresql indexing timestamp postgresql-performance

6
推荐指数
1
解决办法
1777
查看次数

PostgreSQL在不同的时区转储和恢复

我有两个数据库在不同时区的不同服务器上运行.有几个表包含timestamp with timezone.

我需要从一个数据库转储数据,并使用正确的时间戳和正确的时区将其导入另一个数据库.

我使用以下命令来转储数据:

pg_dump -a DB_NAME > dump.sql
Run Code Online (Sandbox Code Playgroud)

我看到数据采用旧时间戳和时区格式: 2013-11-29 14:30:00+02

然后我使用命令到另一台服务器来恢复转储:

psql -d DB_NAME -f dump.sql
Run Code Online (Sandbox Code Playgroud)

我看到时间戳和时区来自旧服务器 - 我认为这是正常的.

然后我尝试在dump.sql的开头添加以下命令

SET timezone ...
Run Code Online (Sandbox Code Playgroud)

但仍然行不通.:(

这是一次性操作.一旦传输数据不需要同步.有没有办法使用pg_dump和pg_restore或类似的方式进行此类转换?

postgresql timezone timestamp pg-dump pg-restore

6
推荐指数
1
解决办法
1500
查看次数

基于检查约束的分区修剪未按预期工作

为什么下面的查询计划中包含表“events_201504”?根据我的查询和该表的检查约束,我希望查询规划器能够完全修剪它:

database=# \d events_201504
                                   Table "public.events_201504"
    Column     |            Type             |                           Modifiers
---------------+-----------------------------+---------------------------------------------------------------
 id            | bigint                      | not null default nextval('events_id_seq'::regclass)
 created_at    | timestamp without time zone |
Indexes:
    "events_201504_pkey" PRIMARY KEY, btree (id)
    "events_201504_created_at" btree (created_at)
Check constraints:
    "events_201504_created_at_check" CHECK (created_at >= '2015-04-01 00:00:00'::timestamp without time zone AND created_at <= '2015-04-30 23:59:59.999999'::timestamp without time zone)
Inherits: events
Run Code Online (Sandbox Code Playgroud)

时间及配置:

database=# select now();
              now
-------------------------------
 2015-05-25 16:49:20.037815-05

database=# show constraint_exclusion;
 constraint_exclusion
----------------------
 on
Run Code Online (Sandbox Code Playgroud)

查询计划:

database=# explain select count(1) from events where created_at …
Run Code Online (Sandbox Code Playgroud)

sql postgresql database-partitioning postgresql-performance postgresql-9.3

6
推荐指数
1
解决办法
3774
查看次数

将索引添加到带时区的时间戳

我想改进这个慢查询,我想添加一个索引,但我不知道哪种索引类型更适合我的情况。

SELECT COUNT(*) ct FROM events
WHERE dtt AT TIME ZONE 'America/Santiago'
   >= date(now() AT TIME ZONE 'America/Santiago') + interval '1s'  
Run Code Online (Sandbox Code Playgroud)

查询计划:

"Aggregate  (cost=128032.03..128032.04 rows=1 width=0) (actual time=3929.083..3929.083 rows=1 loops=1)"
"  ->  Seq Scan on events  (cost=0.00..125937.68 rows=837742 width=0) (actual time=113.080..3926.972 rows=25849 loops=1)"
"        Filter: (timezone('America/Santiago'::text, dtt) >= (date(timezone('America/Santiago'::text, now())) + '00:00:01'::interval))"
"        Rows Removed by Filter: 2487386"
"Planning time: 0.179 ms"
"Execution time: 3929.136 ms"
Run Code Online (Sandbox Code Playgroud)
  • 查询获取当天事件的计数。
  • dtt 是带有时区列的时间戳。
  • 我正在使用 Postgresql 9.4。

注意:根据 Erwin 的建议,查询运行得更快一些,但我认为还不够快。

"Aggregate  (cost=119667.76..119667.77 rows=1 width=0) (actual …
Run Code Online (Sandbox Code Playgroud)

sql postgresql indexing timezone count

6
推荐指数
1
解决办法
5476
查看次数