如何将复杂类型的数组成员与SELECT进行比较?

时间:2018-03-28 09:12:07

标签: postgresql postgresql-9.6

给出一个这样的表:

╔══════════════════════════════════════╤════════╤═══════════╗
║ message_id                           │ type   │ json_data ║
╠══════════════════════════════════════╪════════╪═══════════╣
║ 2c8c86b7-4867-494a-88bf-1e6b17dd121f │ type-a │ {}        ║
╟──────────────────────────────────────┼────────┼───────────╢
║ 767d6fbf-84cf-4baa-9e33-46b15f0c8594 │ type-b │ {}        ║
╟──────────────────────────────────────┼────────┼───────────╢
║ 298dcedb-b51d-4623-89f8-fabec44663c8 │ type-c │ {}        ║
╚══════════════════════════════════════╧════════╧═══════════╝

和类似如下的类型:

CREATE TYPE public.new_stream_message AS (
  message_id    UUID,
  "type"        VARCHAR(128),
  json_data     VARCHAR,
  json_metadata VARCHAR
);

和一个函数,它将这些参数作为参数之一。

在这个函数里面我把这个数组写到表中。如果存在唯一约束违规,我想将数组中的message_id与该表中的select语句进行比较。如果一切都匹配,那么这是一个幂等写,我可以放心地忽略异常。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

这样的东西
CREATE OR REPLACE FUNCTION idempotentAppend(streamId varchar, new_stream_message NewMessage[]) RETURNS AppendResult AS $$
DECLARE
    ...
BEGIN

    ...

    foreach message in ARRAY newMessages
    loop
        BEGIN
          INSERT INTO public.Messages (message_id, Type, JsonData, json_metadata)
          SELECT message.*;
        EXCEPTION WHEN unique_violation THEN
            SELECT * FROM public.Messages into conflict WHERE public.Messages.Id = Id;
            IF message.type != conflict.type OR message.json_data != conflict.json_data THEN
                RAISE unique_violation USING MESSAGE = 'Duplicate message ID: ' || Id;
            END IF;
        END;
    end loop;

    ...

END;
$$ LANGUAGE plpgsql;

顺便说一句,我在ddd-cqrs-es slack的#sql-stream-store通道中发现了这个问题,并且一直在研究java版本。

编辑:Whelp ......看起来我应该阅读更多松弛频道。看起来你已经解决了它