是否可以编写一个处理多对多连接的 postgres 函数?

Is it possible to write a postgres function that will handle a many to many join?

我有工作table。我有一个行业 table。工作和行业通过名为 industriesjobs 的联接 table 建立多对多关系。两个 tables 都有 uuid 是它们的主键。我的问题有两个。首先写两个函数这样插入数据是否可行?如果这是可行的,那么我的第二个问题是如何表达 uuid 列类型的数组。我不确定语法。

CREATE OR REPLACE FUNCTION linkJobToIndustries(jobId uuid, industiresId uuid[]) RETURNS void AS $$
DECLARE
    industryId uuid[];
BEGIN
    FOREACH industryId SLICE 1 IN ARRAY industriesId LOOP
        INSERT INTO industriesjobs (industry_id, job_id) VALUES (industryId, jobId);
    END LOOP;
    RETURN;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION insertJobWithIndistries(orginsation varchar, title varchar, addressId uuid, industryIds uuid[]) RETURNS uuid AS $$
DECLARE
    jobId uuid;
BEGIN
    INSERT INTO jobs ("organisation", "title", "address_id") VALUES (orginsation, title, addressId)  RETURNING id INTO jobId;
    SELECT JobbaLinkJobToIndustries(jobId, industryIds);
END;
$$ LANGUAGE plpgsql;

SELECT jobId FROM insertJobWithIndistries(
    'Acme Inc'::varchar, 
    'Bomb Tester'::varchar, 
    '0030cfb3-1a03-4c5a-9afa-6b69376abe2e',
    { 19c2e0ee-acd5-48b2-9fac-077ad4d49b19, 21f8ffb7-e155-4c8f-acf0-9e991325784, 28c18acd-99ba-46ac-a2dc-59ce952eecf2 }
);

提前致谢。

解决方案的关键是函数 unnest() 到(根据文档):

expand an array to a set of rows

还有一个data-modifying CTE.

一个简单的查询就可以完成工作:

WITH ins_job AS (
   INSERT INTO jobs (organisation, title, address_id)
   SELECT 'Acme Inc', 'Bomb Tester', '0030cfb3-1a03-4c5a-9afa-6b69376abe2e'  -- job-data here
   RETURNING id
   )
INSERT INTO industriesjobs (industry_id, job_id)
SELECT indid, id
FROM   ins_job i  -- that's a single row, so a CROSS JOIN is OK
     , unnest('{19c2e0ee-acd5-48b2-9fac-077ad4d49b19
              , 21f8ffb7-e155-4c8f-acf0-9e9913257845
              , 28c18acd-99ba-46ac-a2dc-59ce952eecf2}'::uuid[]) indid;  -- industry IDs here

还演示了 uuid 数组的正确语法。 (元素和分隔符之间的白色 space 不在双引号内时无关紧要。)

您的一个 UUID 短了一个字符:
21f8ffb7-e155-4c8f-acf0-9e991325784
必须类似于:
21f8ffb7-e155-4c8f-acf0-9e9913257845 -- 多一个字符

如果您需要功能,您也可以这样做:

CREATE OR REPLACE FUNCTION link_job_to_industries(_jobid uuid, _indids uuid[])
  RETURNS void AS
$func$
   INSERT INTO industriesjobs (industry_id, job_id)
   SELECT _indid, _jobid
   FROM   unnest(_indids) _indid;
$func$ LANGUAGE sql;

等等

相关:

  • Insert data in 3 tables at a time using Postgres
  • How to insert multiple rows using a function in PostgreSQL