仅当记录存在时才插入到Postgres表中

时间:2019-07-12 19:48:43

标签: sql postgresql plpgsql exists

我正在Postgres中编写一些SQL以更新审核表。我的sql将根据某些条件更新要审核的表,然后选择该更新的记录以更新审核表中的信息。这是我到目前为止的内容:

bool

我的理解是,如果表中没有任何内容与该查询匹配(并且目前没有),则DO $$ DECLARE jsonValue json; revId int; template RECORD; BEGIN jsonValue = '...Some JSON...' UPDATE projectTemplate set json = jsonValue where type='InstallationProject' AND account_id IS NULL; template := (SELECT pt FROM ProjectTemplate pt WHERE pt.type='InstallationProject' AND pt.account_id IS NULL); IF EXISTS (template) THEN ( revId := nextval('hibernate_sequence'); insert into revisionentity (id, timestamp) values(revId, extract(epoch from CURRENT_TIMESTAMP)); insert into projectTemplate_aud (rev, revtype, id, name, type, category, validfrom, json, account_id) VALUES (revId, 1, template.id, template.name, template.type, template.category, template.validfrom, jsonValue, template.account_id); ) END $$; 将是未定义的。我想这样做,以便在template不存在的情况下我的查询不会尝试更新审核表。

我该怎么做才能更新此sql以使其与我要执行的操作相符?

1 个答案:

答案 0 :(得分:2)

您不能像这样使用EXISTS,它需要一个 subquery 表达式。加上代码的其他一些问题。

具有数据修改CTE的单个SQL DML语句应正确替换您的DO命令。而且更快:

WITH upd AS (
   UPDATE ProjectTemplate
   SET    json = '...Some JSON...'
   WHERE  type = 'InstallationProject'
   AND    account_id IS NULL
   RETURNING *
   )
, ins AS (
   INSERT INTO revisionentity (id, timestamp)
   SELECT nextval('hibernate_sequence'), extract(epoch FROM CURRENT_TIMESTAMP)
   WHERE  EXISTS (SELECT FROM upd)  -- minimal valid EXISTS expression!
   RETURNING id
   )
INSERT INTO ProjectTemplate_aud
      (rev , revtype,   id,   name,   type,   category,   validfrom,   json,   account_id)
SELECT i.id, 1      , u.id, u.name, u.type, u.category, u.validfrom, u.json, u.account_id
FROM   upd u, ins i;

如果revisionentity发现任何行,则在UPDATE中插入行。

插入projectTemplate_aud行与已更新的行一样多。

关于修改数据的CTE:

此外:我看到混合使用CaMeL大小写,一些下划线或只是小写的名称。仅考虑合法的小写名称(并避免将基本类型名称用作列名称)。不过,最重要的是,保持一致。相关: