For 循环内的 Postgresql 更新

2023-11-22

我对 postgresql 还很陌生,并且在使用 for 循环更新表中的空值列时遇到问题。我正在处理的表格很大,因此为了简洁起见,我将给出一个较小的示例来说明要点。采取下表

+----+----------+----------+
| id  |  A  | B  |  C       |
+----+----------+----------+
| a   | 1   | 0  |  NULL    |
| b   | 1   | 1  |  NULL    |
| c   | 2   | 4  |  NULL    |
| a   | 3   | 2  |  NULL    |
| c   | 2   | 3  |  NULL    |
| d   | 4   | 2  |  NULL    |
+----+----------+----------+

我想编写一个 for 循环,它迭代所有行并执行一些操作 计算 a 列和 b 列中的值,然后在 c 中插入一个新值。 例如,其中 id = a ,更新表集 C = A*B ,或其中 id = d 设置 C = A + B 等。然后这会给我一个像这样的表

+----+----------+----------+
| id  |  A  | B  |  C       |
+----+----------+----------+
| a   | 1   | 0  |  0       |
| b   | 1   | 1  |  NULL    |
| c   | 2   | 4  |  NULL    |
| a   | 3   | 2  |  6       |
| c   | 2   | 3  |  NULL    |
| d   | 4   | 2  |  6       |
+----+----------+----------+ 

所以最终我想循环遍历表的所有行并根据“id”列中的值更新列 C。我编写的函数(没有给出任何错误,但也没有更新任何内容)看起来像这样......

-- DROP FUNCTION some_function();

CREATE OR REPLACE FUNCTION some_function()
RETURNS void AS
$BODY$
DECLARE
--r integer; not too sure if this needs to be declared or not
result int;

BEGIN

FOR r IN select * from 'table_name' 
LOOP
select(
case
when id = 'a'  THEN B*C
when id = 'd'  THEN B+C
end) 
into result;

update table set C = result 
WHERE id = '';
END LOOP;
RETURN;

END
$BODY$
LANGUAGE plpgsql

我确信我错过了一些愚蠢的东西,可能是我正在返回的东西......在这种情况下无效。但由于我只想更新现有行,我是否需要返回任何内容?可能有比使用循环更简单的方法来做到这一点,但我想使用这种方法让它工作。 如果有人能指出我正确的方向或指出任何明显明显的我做错的事情,我将非常感激。 提前致谢。


不需要循环或函数,这可以通过单个来完成update陈述:

update table_name
  set c = case 
            when id = 'a' then a*b
            when id = 'd' then a+b
            else c -- don't change anything
          end;

SQLFiddle:http://sqlfiddle.com/#!15/b65cb/2

您的函数没有执行任何操作的原因是:

update table set C = result 
WHERE id = '';

您的列中没有包含空字符串的行id。您的函数似乎也使用了错误的公式:when id = 'a' THEN B*C我想应该是:then a*b. As C is NULL最初,b*c也将产生 null。所以即使if您在循环中的更新会找到一行,它将更新为NULL.

您还从游标中错误地检索值。

如果你真的真的想在循环中低效地完成它,你的函数应该看起来像这样(未测试!):

CREATE OR REPLACE FUNCTION some_function()
  RETURNS void AS
$BODY$
DECLARE
  result int;
BEGIN
  -- r is a structure that contains an element for each column in the select list
  FOR r IN select * from table_name
  LOOP
    if r.id = 'a' then 
      result := r.a * r.b;
    end if;
    if r.id = 'b' then 
      result := r.a + r.b;
    end if;

    update table 
      set C = result 
    WHERE id = r.id; -- note the where condition that uses the value from the record variable
  END LOOP;
END
$BODY$
LANGUAGE plpgsql

但再说一遍:如果你的表如你所说“巨大”,那么循环是一个非常糟糕的解决方案。关系数据库是用来处理数据“集”的。逐行处理是一种反模式,几乎总是会产生糟糕的性能。

或者反过来说:进行基于集合的操作(就像我的单update示例)始终是更好的选择。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

For 循环内的 Postgresql 更新 的相关文章

  • 无法安装 psycopg2 (pip install psycopg2)

    我使用的是 MAC 和 python 版本 2 7 14 Collecting psycopg2 Could not fetch URL https pypi python org simple psycopg2 There was a p
  • 使用 for 循环 Python 为数组赋值

    我正在尝试将字符串的值分配给不同的数组索引 但我收到一个名为 列表分配超出范围 的错误 uuidVal distVal uuidArray distArray for i in range len returnedList for beac
  • Postgres jsonb数组:查询非空交集

    假设我有一个名为的 JSONB 列value在表中t 这些 JSON 的内部是tags字段是字符串列表 我想对这些标记的 JSON blob 进行查询 foo or bar 所以假设表数据如下所示 value tags other tags
  • 更改迁移中的自动​​增量值(PostgreSQL 和 SQLite3)

    我有一个托管在 Heroku 上的项目 想要更改表的自动增量起始值 我在本地使用 SQLite3 Heroku 使用 PostgreSQL 这是我在迁移中所拥有的 class CreateMytable lt ActiveRecord Mi
  • 使用 JSON 参数的 Postgres 批量 INSERT 函数

    这是一个plpgsqlpostgres 的函数9 6 它试图INSERT一行 如果插入没有失败 由于违反键约束 那么它会运行更多命令 CREATE FUNCTION foo int text text RETURNS void AS BEG
  • postgreSql 中特定时间后表更新

    我已经在 postgres 中创建了表 现在我想在特定时间 例如 1 小时 后更新一行 我看到很多问题 例如 https dba stackexchange com questions 56424 column auto updated a
  • 跨多个表进行搜索,并在结果行中显示表名称

    如何构建 SQL 语句以跨多个平面不相关的表运行 并使用选择结果和结果来自的表的名称显示结果 这种情况是这样的 我有几个表 每个表都有相同的列名 这是我从外部各方收到的数据 并将其存储在不同的表中 相同的表看起来像 Table 1 pid
  • 重命名重复行

    这是我的问题的一个简化示例 我有一个表 其中有一个包含重复条目的 名称 列 ID Name 1 AAA 2 AAA 3 AAA 4 BBB 5 CCC 6 CCC 7 DDD 8 DDD 9 DDD 10 DDD 进行 GROUP BY 操
  • 具有日期变量的 SSIS For 循环容器

    我想创建一个每月包 在 ODBC 上执行每日查询并写入输出文件 更具体地说 必须首先在上个月的第一天执行查询 e g 01 11 2018 然后下一个 02 11 2018 直到上个月的最后一天 30 11 2018 日期变量当前保存为字符
  • 如何将docker postgres镜像10.3中的pg_restore升级到10.5

    我使用 tableplus 作为我的一般管理员 目前使用 10 3 版本的 docker postgres 镜像进行生产和本地主机开发 因为tableplus将他们的postgres 10驱动程序升级到了10 5 所以我不能再使用pg re
  • 串行类型的外键 - 确保始终手动填充

    我有两个表 国家和地区 CREATE TABLE Countries id SERIAL name VARCHAR 40 NOT NULL PRIMARY KEY id CREATE TABLE Regions id SERIAL coun
  • 无法为数据库添加 SSL 支持

    我正在使用 Spring 3 Hibernate 和 postgres 9 2 为了启用 SSL 数据库连接 我按照以下步骤操作 创建自签名证书 参考 http www postgresql org docs 9 2 static ssl
  • 为什么 PostgreSQL 不能做这个简单的 FULL JOIN 呢?

    这是包含 2 个表的最小设置a and b每行 3 行 CREATE TABLE a id SERIAL PRIMARY KEY value TEXT CREATE INDEX ON a value CREATE TABLE b id SE
  • 将 UNNEST 与 jOOQ 结合使用

    我正在使用 PostgreSQL 9 4 Spring Boot 1 3 2 和 jOOQ 3 7 我想 jOOQify 以下查询 SELECT id FROM users WHERE username IN SELECT FROM UNN
  • 由于键更改而尝试插入时外键约束失败

    我有一个 Content 对象 它引用多对多关系中的一组 Tag 对象 作为持久化新内容对象的一部分 我在 PostgreSQL 中查看标签是否已存在 如果存在 则将对其的引用添加到内容对象并尝试保存内容对象 我遇到的问题是 当我这样做时
  • PostgreSQL-过滤日期范围

    我是一名 SQL 开发人员 大部分时间都花在 MSSQL 上 我正在寻找一种更好的方法来过滤 PostgreSQL 数据库中的 无时区时间戳 字段 我在用着 Where DateField gt 2010 01 01 and DateFie
  • 如何使用 django ORM 在外键字段上连接两个表?

    假设我有以下模型 class Position models Model name models CharField class PositionStats models Model position models ForeignKey P
  • 提高第一个查询的性能

    如果执行以下数据库 postgres 查询 则第二次调用要快得多 我猜第一个查询很慢 因为操作系统 linux 需要从磁盘获取数据 第二个查询受益于文件系统级别和 postgres 中的缓存 有没有一种方法可以优化数据库以快速获得结果fir
  • 从postgresql中的jsonb嵌套数组中删除键值对

    我有 jsonb 数据作为 a b 1 c 2 d 3 b 4 c 5 d 6 g b 1 c 2 d 3 b 4 c 5 d 6 我想从 a 和 g 键的嵌套数组中删除 c 键 是否有一个查询可以执行此操作 SELECT jsonb ob
  • 我不断收到错误“关系 [TABLE] 不存在”

    我一直在尝试查询数据库中的两个表 在服务器资源管理器中 我可以看到两个表 甚至可以看到其中的列 我们将它们称为 Schema table1 和 Schema table2 其中 Schema 的第一个字母大写 我尝试运行以下查询 selec

随机推荐