Postgres UPDATE语句不会更新任何行

时间:2015-09-03 16:03:53

标签: sql postgresql sql-update

我有两张桌子:

"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的情况下尝试了查询,但是因为“名称”错误而失败了。

有人可以告诉我我做错了吗?

2 个答案:

答案 0 :(得分:1)

UPDATE ONLY public."TABLE2" t2
SET    "Description" = t1."unit" -- ::regclass  -- ???
FROM   public."TABLE1" t1
WHERE  t1."Id" = t2."Id";

您确定"TABLE1"是否继承自"TABLE2"?这些名字表明相反。

当目标为regclass时,为什么要投放到varchar?您了解数据类型regclass吗?

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

我删除了演员。

为什么对varchar(255)"Table1".unit使用varchar(250)表示"表2"。"说明"?为什么要使用varchar(255)开头?它通常表示Postgres数据类型varchar尚未被理解:

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

您提到的错误代码P0001 in your comment是PL / pgSQL错误。 The documentation:

Class P0 — PL/pgSQL Error
P0000   plpgsql_error
P0001   raise_exception

"TABLE2"上可能有一个或多个触发器功能,您忘了提及。

答案 1 :(得分:-1)

这应该可以解决问题:

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";