返回数据在returning子句之外的新insert的insert标识

vdgimpew  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(301)

我使用的是postgresql12.3。
类似于关于这个问题的许多问题,比如这个问题,但是我需要使用另一个表中的数据,这个表在returning子句中不存在。
举一个人为的例子,考虑三个表: customers , products ,和 sales ,以及一个场景,其中需要在销售点创建一个客户,并且需要使用 users 以及 products 身份证。

CREATE TABLE public.customers (
    id SERIAL PRIMARY KEY,
    first_name TEXT NOT NULL,
    last_name TEXT NOT NULL
) 

CREATE TABLE public.products (
    id SERIAL PRIMARY KEY,
    product TEXT NOT NULL
)

CREATE TABLE public.sales (
    id SERIAL PRIMARY KEY,
    customer_id INTEGER NOT NULL REFERENCES customers(id),
    product_id INTEGER NOT NULL REFERENCES products(id)
) 

INSERT INTO customers (first_name, last_name) VALUES ('Bob', 'Smith');
INSERT INTO customers (first_name, last_name) VALUES ('Jane', 'Doe');

INSERT INTO products (product) VALUES ('widget 1');
INSERT INTO products (product) VALUES ('widget 2');
INSERT INTO products (product) VALUES ('widget 3');

INSERT INTO sales (customer_id, product_id) VALUES (1, 1);
INSERT INTO sales (customer_id, product_id) VALUES (2, 1);
INSERT INTO sales (customer_id, product_id) VALUES (2, 2);

如果我只需要客户id,以下内容不会有问题:

WITH new_customer_and_new_sale AS (

    INSERT INTO customers (first_name, last_name) VALUES ('John', 'Doe') RETURNING id
)   

INSERT INTO sales (customer_id) 

SELECT id FROM new_user_and_new_sale

sales 如果在returning子句中找不到约束,则上述操作显然不起作用。我曾尝试连接表以获取附加数据,但未能使其正常工作。
请忽略表的结构可能存在的任何小问题,因为我处理的数据有数百列和许多外键。我试着把这个问题浓缩成最简单的形式,冒着看似做作的风险。

93ze6v8z

93ze6v8z1#

你的例子失败了,因为你没有提供 product_id ,这是必需的。
您可以这样直接指定:

WITH inserted_customer AS (
    INSERT INTO customers (first_name, last_name) VALUES ('acacaca', 'Doe') RETURNING id
)
INSERT INTO sales (customer_id, product_id) 
SELECT inserted_customer.id, 2 FROM inserted_customer;

如果您想从现有产品中获取产品id,可以使用子查询(如果您正在做更复杂的事情,可以使用cte)。

WITH inserted_customer AS (
    INSERT INTO customers (first_name, last_name) VALUES ('acacaca', 'Doe') RETURNING id
)
INSERT INTO sales (customer_id, product_id) 
SELECT inserted_customer.id, (SELECT id FROM products ORDER BY id DESC LIMIT 1) FROM inserted_customer;

如果您想即时插入客户和产品,可以执行两个CTE:

WITH inserted_customer AS (
    INSERT INTO customers (first_name, last_name) VALUES ('acacaca', 'Doe') RETURNING id
),
inserted_product AS (
    INSERT INTO products (product) VALUES ('my product') RETURNING id
)   
INSERT INTO sales (customer_id, product_id) 
SELECT inserted_customer.id, inserted_product.id
FROM inserted_customer, inserted_product;

希望这有帮助!

相关问题