【问题标题】:Postgres UPDATE statement doesn't update any rowsPostgres UPDATE 语句不更新任何行
【发布时间】:2015-09-04 06:19:30
【问题描述】:

我有两张桌子:

"TABLE1"

"Id" integer,
"unit" varchar(255)
...

"TABLE2"

"Id" integer,
"Description" varchar(250)
...

TABLE1TABLE2 的后代——用 Postgres 的说法,它“继承”自 TABLE2

TABLE2 的行与TABLE1 中的每一行的“Id”匹配。它还有许多其他后代,TABLE2 中的行数比 TABLE1 中的多。

由于与此处无关的原因,我需要将 TABLE1."unit" 中的文本复制到 TABLE2."Description" 中,以获取 Id 列相同的所有行。

以下查询成功,但不更新任何行:

UPDATE  ONLY public."TABLE2" as t2
SET    ("Description") = (t1."unit"::regclass)
FROM   "TABLE1" as t1
WHERE  t1."Id" = t2."Id";

我尝试了不带ONLY 的查询,但由于“名称”错误而失败。

谁能告诉我我做错了什么?

【问题讨论】:

  • 您混合了双引号标识符和不带引号的标识符,但这在 Postgres 中具有相关性。什么是"name" error?请提供逐字错误消息。 Edit 您的问题是为"TABLE1""TABLE2" 提供完整和逐字 表定义(您在psql 中使用@ 987654341@) 给我们一个战斗的机会。添加可能存在的任何触发器(以及使用的触发器函数)、规则或索引。并且总是你的 Postgres 版本。

标签: sql postgresql sql-update


【解决方案1】:
UPDATE ONLY public."TABLE2" t2
SET    "Description" = t1."unit" -- ::regclass  -- ???
FROM   public."TABLE1" t1
WHERE  t1."Id" = t2."Id";

您确定"TABLE1" 继承自"TABLE2"?名称会相反。

当目标也是varchar 时,为什么还要转换为regclass?你了解regclass的数据类型吗?

如果字符串不是有效的表(或相关)对象,则转换为regclass 会失败并出现异常。在 Postgres 9.4 或更高版本中,您可以使用函数 to_regclass() 而不是为非法标识符返回 NULL:

我删除了演员表。

为什么你用varchar(255) 表示"Table1".unitvarchar(250) 表示“Table2”.“Description”?为什么要使用varchar(255) 开头?它通常表示 Postgres 数据类型 varchar 尚未被理解:

为什么要在查询中对 public."TABLE2" 进行架构限定,而不是 "TABLE1"
为什么要使用那些繁琐的双引号混合大小写标识符开头?

你提到的错误代码P0001in your comment是一个PL/pgSQL错误。 The documentation:

Class P0 — PL/pgSQL Error
P0000   plpgsql_error
P0001   raise_exception

"TABLE2" 上可能有一个或多个触发函数,您忘记提及了。

【讨论】:

    【解决方案2】:

    这应该可以解决问题:

    UPDATE  t2
    SET    "Description" = t1."unit"
    FROM   "TABLE1" as t1
    JOIN   "TABLE2" AS t2 ON t1."Id" = t2."Id"; 
    

    如果单位字段有可能达到 255,则更新表 2 时可能会出现截断错误。

    在这种情况下,您可以查看您的字段以找出违规行:

    SELECT t1."unit", LEN(t1."unit")
    FROM   "TABLE1" as t1
    WHERE LEN(t1."unit") > 250
    

    AND/OR 更新字段,取剩下的 250 个字符

    UPDATE  t2
    SET    "Description" = LEFT(t1."unit", 250)
    FROM   "TABLE1" as t1
    JOIN   "TABLE2" AS t2 ON t1."Id" = t2."Id";
    

    【讨论】:

    • 感谢您的快速回答!不幸的是,我仍然没有有效的解决方案——查询运行了一个多小时,然后出现错误:错误:CM_FORBIDDEN_OPERATION **********错误******** ** 错误:CM_FORBIDDEN_OPERATION SQL 状态:P0001
    • 你完全忽略了提到的继承。更重要的是,建议的 UPDATE 语句在 Postgres 中是完全无效的。 Please consult the manual for basics before you write more misleading answers.
    猜你喜欢
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 2023-03-20
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多