Insérer des données dans des Tables liées par une clé étrangère

J'utilise PostgreSQL.

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

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

Pour insérer une commande, voici ce que je dois faire habituellement,

Par exemple," John "place" 1.34 " ordre de prix.

(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.

Il y a 4 communications SQL avec la base de données impliquées pour cette opération simple!!!

Existe-t-il un meilleur moyen, qui peut être réalisable en utilisant 1 instruction SQL?

42
demandé sur Cheok Yan Cheng 2010-01-04 10:27:06

3 réponses

, Vous pouvez le faire dans une instruction sql pour les clients existants, 3 états pour les nouveaux. Tout ce que vous avez à faire est d'être optimiste et d'agir comme si le client existe déjà:

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

Si le client n'existe pas, vous obtiendrez une exception sql dont le texte sera quelque chose comme:

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

(à condition que vous ayez Rendu customer_id non nullable, ce que je suis sûr que vous l'avez fait). Lorsque cette exception se produit, insérez le client dans la table client et refaites l'insertion dans la commande tableau:

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

À moins que votre entreprise ne se développe à un rythme qui fera "où mettre tout l'Argent" votre seul vrai problème, la plupart de vos inserts seront pour les clients existants. Donc, la plupart du temps, l'exception ne se produira pas et vous aurez terminé dans une déclaration.

48
répondu Wayne Conrad 2010-01-05 23:51:06

Pas avec une instruction régulière, non.

Ce que vous pouvez faire est d'envelopper la fonctionnalité dans une fonction PL/pgsql (ou un autre langage, mais PL/pgsql semble être le plus approprié pour cela), puis appelez simplement cette fonction. Cela signifie que ce sera toujours une seule instruction à votre application.

3
répondu Magnus Hagander 2010-01-04 08:15:24

Utiliser des procédures stockées.

Et même en supposant que vous ne voudriez pas utiliser de procédures stockées - il y a au plus 3 commandes à exécuter, pas 4. Deuxième ID obtenir est inutile, comme vous pouvez le faire "insérer dans ... RETOURNER".

1
répondu 2010-01-04 08:49:45