仅当记录存在时才插入 Postgres table

Insert into Postgres table only if record exists

我正在用 Postgres 编写一些 sql 来更新审计 table。我的 sql 将根据某些标准更新正在审核的 table,然后 select 更新记录以更新审核 table 中的信息。这是我目前所拥有的:

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

我的理解是,如果 table 中没有与该查询匹配的内容(目前没有),则 template 将是未定义的。我想这样做,如果 template 不存在,我的查询将不会尝试更新审计 table。

我该怎么做才能更新此 sql 以匹配我正在尝试做的事情?

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

这个带有 data-modifying 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;

如果 UPDATE 找到任何行,则在 revisionentity 中插入 单个 行。

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

关于 data-modifying 个 CTE:

  • Insert data in 3 tables at a time using Postgres

旁白:我看到 CaMeL-case、一些下划线或只是小写的名称。只考虑合法的 lower-case 名称(并避免将基本类型名称作为列名称)。不过,最重要的是 一致 。相关:

  • Are PostgreSQL column names case-sensitive?