Возвращение идентификатора INSERT для нового INSERT с данными вне предложения RETURNING - PullRequest
0 голосов
/ 11 июля 2020

Я использую PostgreSQL 12.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);

Если мне нужен только идентификатор клиента, следующее не будет проблемой:

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 имеет ограничения, не найденные в предложении возврата, очевидно, что вышеуказанное не сработает. Я пробовал объединить таблицы, чтобы получить дополнительные данные, но не смог заставить их работать.

Пожалуйста, не обращайте внимания на любые незначительные проблемы, которые могут возникнуть со структурой таблиц, поскольку данные я Я работаю с сотнями столбцов и множеством внешних ключей. Я попытался сжать проблему до ее простейшей формы, рискуя показаться надуманной.

1 Ответ

1 голос
/ 11 июля 2020

Ваш пример не работает, потому что вы не предоставляете значение для 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;

Если вы хотите получить идентификатор продукта из существующего продукта, вы можете сделать это с помощью подзапроса (или 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;

Если вы хотите вставить клиента и продукт в fly, вы можете выполнить два 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;

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...