【问题标题】:Insert unique values from array of objects in postgres从 postgres 中的对象数组中插入唯一值
【发布时间】:2019-01-28 02:55:39
【问题描述】:

我一直在尝试将一组唯一代码从一组对象输入到 postgres。这是我到目前为止所拥有的,但它在INTO附近不断失败。我之前尝试过循环版本,但它从来没有插入任何东西,但也不会产生错误。下面将是理想的批量插入,无需任何 FOR 循环。

CREATE OR REPLACE FUNCTION "InsertCodes" (
  "@codes"                  JSONB,
  "@type"                   TEXT
)
RETURNS void AS
$func$
DECLARE "id"                UUID;
BEGIN
  "id" = uuid_generate_v4();
  SELECT * FROM (
    SELECT *
    FROM jsonb_array_elements("@codes")
  ) AS c (
-- fails below
    INSERT INTO
      "codes" (
        "id",
        "code",
        "name",
        "type"
      )
    VALUES (
      "id",
      c."code",
      c."name",
      "@type"
    );
    ON CONSTRAINT ("code")
    DO NOTHING
    RETURNING 1;
  );
END;
$func$ LANGUAGE PLPGSQL;

@codes 如下所示:

[
  {
    "code": 1234,
    "name": "numeric"
  },
  {
    "code": "1k1l2k",
    "name": "alphanumeric"
  }
]

【问题讨论】:

    标签: postgresql sql-insert bulkinsert jsonb


    【解决方案1】:

    查询应如下所示:

    "id" = uuid_generate_v4();
    INSERT INTO "codes" ("id", "code", "name", "type")
    SELECT "id", item->>'code', item->>'name', "@type"
    FROM jsonb_array_elements("@codes") AS item
    ON CONFLICT ("code") DO NOTHING;
    

    请注意,对于作为 jsonb 数组传递的所有代码,都将插入相同的 "id"。如果它是主键,您应该为每个代码分别生成"id"

    INSERT INTO "codes" ("id", "code", "name", "type")
    SELECT uuid_generate_v4(), item->>'code', item->>'name', "@type"
    FROM jsonb_array_elements("@codes") AS item
    ON CONFLICT ("code") DO NOTHING;
    

    【讨论】:

      【解决方案2】:

      很难理解你想要做什么。也许是这样:

      CREATE OR REPLACE FUNCTION "InsertCodes" (
        "@codes"                  JSONB,
        "@type"                   TEXT
      )
      RETURNS void AS
      $func$
      DECLARE "id"                UUID;
      BEGIN
        "id" = uuid_generate_v4();
      
        with c("code", "name") as
        (
        SELECT codes->>'code', codes->>'name'
        FROM jsonb_array_elements("@codes") t(codes)
        ) 
      -- fails below
          INSERT INTO 
            "codes" (
              "id",
              "code",
              "name",
              "type"
            )
          select 
            "id",
            c."code",
            c."name",
            "@type"
          from c
          ON CONFLICT ON CONSTRAINT "code"
          DO NOTHING;
      END;
      $func$ LANGUAGE PLPGSQL;
      

      【讨论】:

        猜你喜欢
        • 2014-04-03
        • 1970-01-01
        • 1970-01-01
        • 2022-11-15
        • 2020-11-13
        • 2019-10-20
        • 2017-09-08
        • 1970-01-01
        相关资源
        最近更新 更多