多个插入PostgreSQL

时间:2018-03-19 18:58:07

标签: sql postgresql

我正在尝试从1个sql查询执行多个插入。要打破我在这里要做的是数据库结构:

links:
  - id // uuid_generate_v4()
  - hash

permissions:
  - id // uuid_generate_v4()
  - name

photos:
  - id // uuid_generate_v4()
  - url

link_permissions:
  - link_id
  - permission_id

link_photo:
  - link_id
  - photo_id

现在每当我插入链接时,我都需要插入其权限和照片。这是我到目前为止尝试过的SQL查询。

WITH link as (
    INSERT INTO links(hash) VALUES ('my-random-hash') 
    RETURNING *
) 
INSERT INTO link_photo(link_id, photo_id) 
VALUES ((select link.id from link), '095ccacf-ebc1-4991-8ab0-cac13dac02b7'), 
INSERT INTO link_permission(link_id, permission_id) 
VALUES ((select link.id from link), '506f3302-fe9f-4982-8439-d6781f646d01')

WITH link as (
  INSERT INTO links(hash) VALUES ('my-random-hash') 
  RETURNING *
) 
(INSERT INTO link_photo(link_id, photo_id) 
  VALUES ((select link.id from link), '095ccacf-ebc1-4991-8ab0-cac13dac02b7')), 
 INSERT INTO link_permission(link_id, permission_id) 
 VALUES ((select link.id from link), '506f3302-fe9f-4982-8439-d6781f646d01')

我该如何撰写此查询?

4 个答案:

答案 0 :(得分:3)

将第二个插入物插入另一个CTE:

WITH link as (
    INSERT INTO links(hash) VALUES ('my-random-hash') 
    RETURNING *
) , lp as (
  INSERT INTO link_photo(link_id, photo_id) 
  VALUES ((select link.id from link), '095ccacf-ebc1-4991-8ab0-cac13dac02b7')
)
INSERT INTO link_permission(link_id, permission_id) 
VALUES ((select link.id from link), '506f3302-fe9f-4982-8439-d6781f646d01');

或者,不要使用values,这会使查询更容易阅读(我认为)

WITH link as (
    INSERT INTO links(hash) VALUES ('my-random-hash') 
    RETURNING *
) , lp as (
  INSERT INTO link_photo(link_id, photo_id) 
  select id, '095ccacf-ebc1-4991-8ab0-cac13dac02b7'
  from link
)
INSERT INTO link_permission(link_id, permission_id) 
select id, '506f3302-fe9f-4982-8439-d6781f646d01'
from link;

答案 1 :(得分:1)

Postgresql""查询"只适用于一个州。

你可以在"一次跑步"通过使用anonymous code block,但创建一个合适的plpgsql插入函数可能是一个更好的主意。

答案 2 :(得分:1)

  

现在每当我插入链接时,我都需要插入其权限和照片。

有几种方法可以实现这一目标。您可以使用returning id into link_id将链接ID放入变量link_id中,并在以后的语句中引用它。

由于这一切都必须一致发生,你可以编写一个函数来处理它。这确保它总是一起发生,你不必尝试将它们全部塞进一个语句中,这样就可以更容易地使用变量。如果任何部分失败,您还可以添加事务和错误处理。

create function add_link( photo_id uuid, permission_id uuid)
    returns uuid
    as
$func$
declare
    link_id uuid;
begin   
    insert into links(id, hash)
    values (default, 'probably have the function generate this?')
    returning id into link_id;

    insert into link_photo(link_id, photo_id)
    values (link_id, photo_id);

    insert into link_permission(link_id, permission_id)
    values (link_id, permission_id);

    return link_id;
end
$func$ language plpgsql;
test=# select * from add_link(uuid_generate_v4(), uuid_generate_v4());
               add_link               
--------------------------------------
 1c18b24c-c7ac-4169-8449-1c18c9087f8b
(1 row)

答案 3 :(得分:0)

如果您更换了" RETURNING *"那么您的第一次尝试工作(我还没有尝试过)用" RETURNING id"然后选择那个。

有关完整查询,请参阅the answer to this question