Postgresql多对多关系插入

Postgresql多对多关系插入,postgresql,sql-insert,Postgresql,Sql Insert,我正在使用PostResql9.3.5。实体“Foo”和“Bar”之间存在多对多关系,我将其建模为: CREATE TABLE Foo ( id SERIAL PRIMARY KEY NOT NULL, .... various columns for foo .... ); CREATE TABLE Bar ( id SERIAL PRIMARY KEY NOT NULL, field1 varchar(50) UNIQUE NOT NULL, ...

我正在使用PostResql9.3.5。实体“Foo”和“Bar”之间存在多对多关系,我将其建模为:

CREATE TABLE Foo
(
    id SERIAL PRIMARY KEY NOT NULL,
    .... various columns for foo ....
);

CREATE TABLE Bar
(
    id SERIAL PRIMARY KEY NOT NULL,
    field1 varchar(50) UNIQUE NOT NULL,
    .... various columns for bar ....
);

CREATE TABLE FooBar
(
    fooID int NOT NULL,
    barID int NOT NULL,
    PRIMARY KEY (fooID, barID),
    FOREIGN KEY (fooID) REFERENCES Foo(id),
    FOREIGN KEY (barID) REFERENCES Bar(id)
);
INSERT INTO Bar(field1, .... other fields for Bar....) 
SELECT 'value1', .... other values for the insert....
WHERE NOT EXISTS (
SELECT 1 FROM Bar WHERE field1 = 'value1')
现在我要做的是在Foo中插入一条记录,在Bar中插入一条对应的记录,然后插入匹配的FooBar记录,其中包含Foo&Bar条目的id

问题:如果酒吧记录已经存在,我不知道什么时候去插入,所以目前我的酒吧插入看起来像:

CREATE TABLE Foo
(
    id SERIAL PRIMARY KEY NOT NULL,
    .... various columns for foo ....
);

CREATE TABLE Bar
(
    id SERIAL PRIMARY KEY NOT NULL,
    field1 varchar(50) UNIQUE NOT NULL,
    .... various columns for bar ....
);

CREATE TABLE FooBar
(
    fooID int NOT NULL,
    barID int NOT NULL,
    PRIMARY KEY (fooID, barID),
    FOREIGN KEY (fooID) REFERENCES Foo(id),
    FOREIGN KEY (barID) REFERENCES Bar(id)
);
INSERT INTO Bar(field1, .... other fields for Bar....) 
SELECT 'value1', .... other values for the insert....
WHERE NOT EXISTS (
SELECT 1 FROM Bar WHERE field1 = 'value1')
这很好,但我的问题是:如何获取新插入(或现有)的Bar记录的id,以便将其插入到FooBar表中?

试试这个

INSERT INTO Bar(field1, field2,etc...) values(value1, value2,etc...) RETURNING id;

这似乎是可行的,尽管它远不是优雅的,而且可能效率很低:

WITH new AS (
    INSERT INTO bar(field1) 
    SELECT ('aaa') WHERE NOT EXISTS (
        SELECT 1 FROM bar WHERE field1='aaa'
    ) RETURNING id
),
existing AS (
    SELECT id FROM bar WHERE field1='aaa'
) 
SELECT id FROM existing UNION SELECT id FROM new
我想这将是低效的,因为在搜索栏中重复搜索匹配值。一个更有效的解决方案可能是编写一个存储过程。

问题是:“如果Bar记录已经存在,我不知道什么时候插入它们”。如果在记录已经存在时执行此操作,则会导致错误。