在 PostgreSQL 中使用关联数组进行批量更新

Posted

技术标签:

【中文标题】在 PostgreSQL 中使用关联数组进行批量更新【英文标题】:Bulk update with associative array in PostgreSQL 【发布时间】:2015-12-15 23:29:54 【问题描述】:

假设我有一个关联数组(用另一种语言定义),如下所示:

apply = 
  'qwer': ['tju', 'snf', 'rjtj', 'sadgg']
  'asdf': ['rtj', 'sfm', 'rtjt', 'adjdj']
  ...
  'zxcv': ['qwr', 'trj', '3w4u', '3tt3']

我有一张这样的桌子:

CREATE TABLE apples (
id integer,
name varchar(10),
key varchar(10),
value varchar(10)
);

如果apples.valueapply 变量的列表之一中,我想应用更新,然后将apples.key 设置为数组的键。如果apples.valuetju,则将apples.key 设置为qwer

我目前的方法是这样的(将 PostgreSQL 与任何程序语言混合):

for key in apply.keys:
  UPDATE apples SET key=$key
  FROM (SELECT unnest(array($apply[key])) AS value) AS update_table
  WHERE value=update_table.value

我想在一个语句中做到这一点。

【问题讨论】:

我不相信有一种方法可以在文字单一的声明中做到这一点。在你的代码中肯定有一个函数(存储过程)或一个智能数据库库,但作为直接的 SQL,我持怀疑态度。不过,我赞成这个问题,因为它很有趣,而且我想被证明是错误的。 @user3137702:总有办法的。 Postgres 有大量的字符串函数。不过,通常情况下,转换为源语言中兼容的数据类型会更聪明/更不容易出错。我添加了一个概念证明。 【参考方案1】:

作为给定示例的概念证明,字符串格式与您显示的完全相同:

演示一个准备好的语句,就像您的客户可能使用的那样。

PREPARE my_update AS
UPDATE apples a
SET    key = upd.key
FROM  (
   SELECT trim (split_part(key_val, ': ', 1), ' ''') AS key
        , string_to_array(translate(split_part(key_val, ': ', 2), '[]''', ''), ', ') AS val_arr
   FROM   unnest(string_to_array(trim($1, E'\n'), E'\n')) key_val
   ) upd
WHERE  a.value = ANY(upd.val_arr);

EXECUTE 在同一会话中任意次数:

EXECUTE my_update($assoc_arr$
  'qwer': ['tju', 'snf', 'rjtj', 'sadgg']
  'asdf': ['rtj', 'sfm', 'rtjt', 'adjdj']
  'zxcv': ['qwr', 'trj', '3w4u', '3tt3']
$assoc_arr$);

SQL Fiddle.

相关:

Insert text with single quotes in PostgreSQL Split given string and prepare case statement

但我宁愿以原始语言处理类型并分别传递keyval_arr

【讨论】:

以上是关于在 PostgreSQL 中使用关联数组进行批量更新的主要内容,如果未能解决你的问题,请参考以下文章

在 PostgreSql 中批量更新或删除哪个更高效?

在 postgreSql 上使用 ParameterizedPreparedStatementSetter 与 BatchPreparedStatementSetter 进行批量更新?

使用 Node.js/Sequelize 进行批量插入时 PostgreSQL 崩溃

PostgreSQL使用函数的多表关联视图在排序时的性能问题

如何使用 Sequelize 和 node.js 进行批量插入

arcgis如何批量进行表关联