Подтвердить что ты не робот

Вставка данных в таблицы, связанные с внешним ключом

Я использую PostgreSQL.

Customer
==================
Customer_ID | Name

Order
==============================
Order_ID | Customer_ID | Price

Чтобы вставить заказ, вот что мне нужно сделать обычно,

Например, "Джон" разместил оцененный заказ "1.34".

(1) Get Customer_ID from Customer table, where name is "John"
(2) If there are no Customer_ID returned (There is no John), insert "John"
(3) Get Customer_ID from Customer table, where name is "John"
(4) Insert "Customer_ID" and "1.34" into Order table.

Для этой простой операции существует 4 связи SQL с базой данных.

Есть ли лучший способ, который может быть достигнут с помощью 1 инструкции SQL?

4b9b3361

Ответ 1

Вы можете сделать это в одном заявлении sql для существующих клиентов, 3 операторах для новых. Все, что вам нужно сделать, это быть оптимистом и действовать так, как будто клиент уже существует:

insert into "order" (customer_id, price) values \
((select customer_id from customer where name = 'John'), 12.34);

Если клиент не существует, вы получите исключение sql, текст которого будет выглядеть примерно так:

null value in column "customer_id" violates not-null constraint

(при условии, что вы сделали customer_id недействительным, что, я уверен, вы сделали). Когда это исключение произойдет, вставьте клиента в таблицу клиентов и повторите ввод в таблицу заказов:

insert into customer(name) values ('John');
insert into "order" (customer_id, price) values \
((select customer_id from customer where name = 'John'), 12.34);

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

Ответ 2

Не с регулярным утверждением, нет.

Что вы можете сделать, так это обернуть функциональность в функции PL/pgsql (или на другом языке, но PL/pgsql, по-видимому, наиболее подходит для этого), а затем просто вызовите эту функцию. Это означает, что это все равно будет одним выражением для вашего приложения.

Ответ 3

Используйте хранимые процедуры.

И даже если вы предпочтете не использовать хранимые процедуры - должно выполняться не более трех команд, а не 4. Второй идентификатор становится бесполезным, так как вы можете делать "ВСТАВИТЬ В... ВОЗВРАТ".