我有两张桌子:
"TABLE1"
"Id" integer,
"unit" varchar(255)
...
"TABLE2"
"Id" integer,
"Description" varchar(250)
...
TABLE1
是TABLE2
的后代 - 在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
的情况下尝试了查询,但是因为“名称”错误而失败了。
有人可以告诉我我做错了吗?
答案 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";