将数据插入到由外键链接的表中

时间:2010-01-04 07:27:07

标签: sql postgresql

我正在使用PostgreSQL。

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

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

要插入订单,这是我通常需要做的事情,

例如,“John”发出“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语句可以实现?

3 个答案:

答案 0 :(得分:49)

您可以在一个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不可为空,我相信你已经这样做了)。发生该异常时,将客户插入到customer表中并将插入重做到订单表中:

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

除非您的业务增长的速度会使“将所有资金放在哪里”是您唯一真正的问题,否则您的大多数插入都将针对现有客户。因此,大多数情况下,异常不会发生,您将在一个声明中完成。

答案 1 :(得分:3)

没有常规声明,没有。

你可以做的是将功能包装在PL / pgsql函数(或其他语言,但PL / pgsql似乎是最合适的),然后只需调用该函数。这意味着它仍然是您的应用程序的单一声明。

答案 2 :(得分:1)

使用存储过程。

即使假设你不想使用存储过程 - 最多只能运行 3命令,而不是4.第二次获取id是没用的,因为你可以“INSERT INTO .. 。退货“。