小编Dav*_*vis的帖子

在 PostgreSQL 中实现 UPSERT 的惯用方式

我已经阅读了UPSERTPostgreSQL 中的不同实现,但所有这些解决方案都相对较旧或相对奇特(例如,使用可写 CTE)。

而且我根本不是 psql 专家,无法立即找出这些解决方案是否过时,因为它们被很好地推荐,或者它们(好吧,几乎所有这些都是)只是不适合生产使用的玩具示例。

在 PostgreSQL 中实现 UPSERT 的最线程安全的方法是什么?

postgresql plpgsql upsert

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

忽略重复插入的最佳方法?

背景

此问题与使用 PostgreSQL 9.2 或更高版本忽略重复插入有关。我问的原因是因为这段代码:

  -- Ignores duplicates.
  INSERT INTO
    db_table (tbl_column_1, tbl_column_2)
  VALUES (
    SELECT
      unnseted_column,
      param_association
    FROM
      unnest( param_array_ids ) AS unnested_column
  );
Run Code Online (Sandbox Code Playgroud)

代码不受检查现有值的影响。(在这种特殊情况下,用户并不关心插入重复项的错误——插入应该“正常工作”。)在这种情况下添加代码来显式测试重复项会带来复杂性。

问题

在 PostgreSQL 中,我找到了几种忽略重复插入的方法。

忽略重复 #1

创建一个捕获唯一约束违规的事务,不采取任何行动:

  BEGIN
    INSERT INTO db_table (tbl_column) VALUES (v_tbl_column);
  EXCEPTION WHEN unique_violation THEN
    -- Ignore duplicate inserts.
  END;
Run Code Online (Sandbox Code Playgroud)

忽略重复 #2

创建规则以忽略给定表上的重复项:

CREATE OR REPLACE RULE db_table_ignore_duplicate_inserts AS
    ON INSERT TO db_table
   WHERE (EXISTS ( SELECT 1
           FROM db_table
          WHERE db_table.tbl_column = NEW.tbl_column)) DO INSTEAD NOTHING;
Run Code Online (Sandbox Code Playgroud)

问题

我的问题主要是学术性的:

  • 什么方法最有效?
  • 什么方法最容易维护,为什么? …

postgresql constraint insert duplication unique-constraint

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

转换测量单位

希望为一系列物质计算最合适的计量单位,其中物质以不同(但兼容)的单位体积给出。

单位换算表

单位转换表存储各种单位以及这些单位之间的关系:

id  unit          coefficient                 parent_id
36  "microlitre"  0.0000000010000000000000000 37
37  "millilitre"  0.0000010000000000000000000 5
 5  "centilitre"  0.0000100000000000000000000 18
18  "decilitre"   0.0001000000000000000000000 34
34  "litre"       0.0010000000000000000000000 19
19  "dekalitre"   0.0100000000000000000000000 29
29  "hectolitre"  0.1000000000000000000000000 33
33  "kilolitre"   1.0000000000000000000000000 35
35  "megalitre"   1000.0000000000000000000000 0
Run Code Online (Sandbox Code Playgroud)

按系数排序表明将parent_id子单元与其上级数值联系起来。

可以使用以下命令在 PostgreSQL 中创建此表:

CREATE TABLE unit_conversion (
  id serial NOT NULL, -- Primary key.
  unit text NOT NULL, -- Unit of measurement name.
  coefficient numeric(30,25) NOT NULL DEFAULT 0, -- Conversion value.
  parent_id integer …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql postgresql-9.1 number-formatting

10
推荐指数
1
解决办法
4597
查看次数

将二维数组从 n 行转置为 2 列

背景

使用 PostgreSQL 9.1,所以WITH ORDINAL(9.4 特性)不可用。

问题

希望简化旋转二维数组的代码。

代码

一个说明问题的工作,过于冗长的例子是:

SELECT
  u.aspect,
  u.preference
FROM (
  SELECT
    t.aspect_preference AS aspect,
    -- Skip every second row
    seq % 2 AS seq,
    lead( aspect_preference, 1 ) OVER (ORDER BY t.seq) AS preference
  FROM (
    SELECT
      unnest( '{ {"COLOUR_SCHEME", "RASPBERRY_BLISS"}, {"FONT", "TERMES_HEROS"}, {"LIST_LAYOUT", "BULLET_SNOWFLAKE"} }'::text[] ) aspect_preference,
      -- Maintain array order after unnesting to a result set
      generate_series( 1,
       (array_ndims( '{ {"COLOUR_SCHEME", "RASPBERRY_BLISS"}, {"FONT", "TERMES_HEROS"}, {"LIST_LAYOUT", "BULLET_SNOWFLAKE"} }'::text[] ) *
        array_length( '{ …
Run Code Online (Sandbox Code Playgroud)

postgresql pivot array

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

稳定(或不可变)函数可以调用 volatile 函数吗?

PostgreSQL文档状态:

任何有副作用的函数都必须标记为 VOLATILE...

考虑以下函数:

CREATE OR REPLACE FUNCTION count_items()
  RETURNS integer AS
$BODY$
DECLARE
  v_result INTEGER DEFAULT 0;
BEGIN
  SELECT
    count( t.id )
  INTO
    v_result
  FROM
    some_table t;

  RETURN v_result;

EXCEPTION
  WHEN OTHERS THEN
    PERFORM error_log_insert( SQLSTATE, SQLERRM, current_query() );
    RETURN 0;
END;
$BODY$
  LANGUAGE plpgsql STABLE
  COST 10;
Run Code Online (Sandbox Code Playgroud)

由于error_log_insert更改数据库(对异常执行插入),这是否意味着该count_items函数具有副作用(尽管是间接的),因此不能声明STABLE,但必须声明VOLATILE

换句话说,函数的稳定性或波动性是否也取决于它在其异常块中调用的函数?

如果是这种情况,那么您将如何STABLE在 PostgreSQL 中创建将所有异常记录到数据库表中的函数?

postgresql logs exception

4
推荐指数
2
解决办法
1302
查看次数

在软件开发生命周期中升级生产数据库

背景

使用 Oracle,有许多工具可以帮助将开发更改迁移和应用到生产环境中(例如Embarcadero Change Manager)。这些工具可以配置为在几乎不需要人工干预的情况下执行任何数据库 DDL 升级。

问题

我有运行 PostgreSQL 9.x 的开发和生产服务器。在将数据库 DDL 初始部署到生产服务器后,我将继续对开发数据库进行更改。这些更改将包括对存储过程的错误修复、对表的更改、附加序列、新视图、更多类型、更多表等。

以自动方式(或几乎自动)升级/迁移生产 PostgreSQL 数据库应用程序的 DDL 以使其在开发中进行新更改的步骤是什么?

有关的

谢谢!

postgresql ddl upgrade

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