I have been trying to input an array of unique codes into postgres from an array of objects. This is what I have so far but it keeps on failing near INTO. I have tried a loop version before but it never ended up insert anything but would not create an error either. The below would be ideal, bulk-inserting without the need for any FOR loops.
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
looks like the below:
[
{
"code": 1234,
"name": "numeric"
},
{
"code": "1k1l2k",
"name": "alphanumeric"
}
]
The query should look like this:
"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;
Note that the same "id"
will be inserted for all codes passed as jsonb array. If it is a primary key you should rather generate the "id"
for each code separately:
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;