postgres中的多个嵌套更新/插入语句

时间:2013-06-14 08:33:09

标签: sql postgresql

我有问题,我必须在我的数据库的表上插入并更新另一个带有id的表,插入提供了我。 我试过这个:

UPDATE events SET mail_key = (
INSERT INTO mail_keys 
    SELECT (name) FROM events)
RETURNING id);

但它不起作用。错误是:

ERROR:  Syntax Error at »INTO«
LINE 2:  INSERT INTO mail_keys 

它有点简化,因为我没有选择名称,而是选择名称的标准化版本,这不会在这里产生问题。

有人有想法吗? 这个陈述将在更多的表(俱乐部,人员......)上重复,所以我有几个表的唯一键。 如果event.name在事件中不是唯一的,那么下一个问题是,如何确保没有创建双重mail_keys。我在mail_keys中有一个唯一的约束。

编辑(更多信息): mail_key表如下所示:

CREATE TABLE sailbook.mail_keys (
id serial,
mail_key character varying(127),
CONSTRAINT mail_key_pk PRIMARY KEY (id),
CONSTRAINT unique_mail_key UNIQUE(mail_key)
);

我想要做的是:我有一个包含事件名称的表,例如:

123 -  Hurricane
242 - Street Art
363 - The Party 2012

俱乐部是这样的:

896 - Town Hall Club
874 - Halo 12
846 - Francist

我想从中创建一个唯一的邮件密钥并将其存储在另一个表中(因为邮件密钥不仅应该是事件的唯一,而且对于俱乐部或人也是如此)。 邮件密钥表将如下所示:

1 - hurricane
2 - street_art
3 - the_party_2012
4 - town_hall_club
5 - halo_12
6 - francist 

事件表看起来像这样:

123 - Hurricane - 1
242 - Street Art - 2
363 - The Party 2012 - 3

俱乐部桌子看起来像这样:

896 - Town Hall Club - 4
874 - Halo 12 - 5 
846 - Francist - 6

2 个答案:

答案 0 :(得分:2)

公共表表达式可用于在单个语句中执行多个更改,如下所述:http://www.postgresql.org/docs/9.1/static/queries-with.html

您将在CTE中插入值,返回将在主查询中执行的更新所需的列。

批量数据的性能优于逐行方法,并且保证语句成功或失败,无需回滚部分成功。

答案 1 :(得分:0)

这个问题的正确方法是匿名函数/方法,它会执行两个或更多语句并保留这样的值:

-- EVENTS
DO $$ 
DECLARE 
  ds record;
  nid integer;
  c integer;
  nwert character varying(4000);
BEGIN
  FOR ds IN (SELECT id, name AS wert FROM events) LOOP
    SELECT count(*) INTO c FROM mail_keys WHERE mail_key = ds.wert; 
    nwert := ds.wert;
    IF (c > 0) THEN   
      nwert := nwert || '_' || ds.id;
    END IF;

    INSERT INTO mail_keys (mail_key) VALUES(nwert) returning id INTO nid;
    UPDATE events SET mail_key = nid WHERE id = ds.id;
  END LOOP;
END$$;

解决了这个问题!