Contrainte de vérification reportable dans PostgreSQL
J'ai de la fonction de vérification obligatoire de participation comme suit:
CREATE FUNCTION member_in_has_address()
RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (SELECT *
FROM address a, member_details b
WHERE b.member_id = a.member_id);
END;
$$ LANGUAGE plpgsql;
Ensuite appelé à partir de la contrainte de VÉRIFICATION
ALTER TABLE member_details
ADD CONSTRAINT member_in_has_address_check
CHECK (member_in_has_address());
Pour créer deferable contrainte dans le Standard SQL:
ALTER TABLE member_details
ADD CONSTRAINT member_in_has_address_check
INITIALLY DEFERRED
CHECK (member_in_has_address());
Comment puis-je faire la même chose dans PostgreSQL?
source d'informationauteur Radovan Luptak | 2013-05-01
Vous devez vous connecter pour publier un commentaire.
Vous pouvez deffer contraintes dans Postgresql, de la même manière que dans d'autres SGBDR, mais pour la version actuelle (9.2), vous ne pouvez deffer UNIQUE, CLÉ PRIMAIRE, EXCLURE, et les RÉFÉRENCES. Extrait de
cette page
du manuel:Vous pouvez créer un simple différé clé étrangère de
member_details
àaddress
au lieu de votre contrainte à vérifier, si chaque membre dispose d'une adresse.Mise à JOUR: Vous avez besoin de créer 2 clés étrangères. Un régulière de
address(member_id)
àmember_details(member_id)
. Les autres différée demember_details(member_id)
àaddress(member_id)
.Avec deux clés étrangères, vous serez en mesure de:
member_details
.address
pour les membres à partir de l'étape 1OU
member_details
.Envelopper vos requêtes dans une transaction, et ensuite utiliser un différé de clé étrangère et de contrainte différée déclenche si au moins une adresse s'impose:
Sur une note séparée, normalisé et jolie, mais de mettre les adresses et les coordonnées telles que les e-mails dans un autre de la table d'adresses présente occasionnellement très coloré UI/UX questions. E. g. formé secrétaire évolution de la société et l'adresse de l'ensemble de son patron des contacts au sein de l'entreprise lorsque l'un d'eux commuté à la société B. Oui, vu cela se produire pour de vrai, quand l'INTERFACE utilisateur se comportent différemment à partir d'Outlook...
De toute façon, et fwiw, j'ai constaté qu'il est souvent plus commode de stocker ce genre de choses dans la même table que le contact, c'est à dire adresse1, adresse2, email1, email2, etc. Il fait d'autres choses plus simples pour une variété d'autres raisons, à savoir les contrôles d'exécution comme celle que vous cherchez. Le cas extrêmement rare où vous voulez stocker plus de deux de ces éléments d'information sont, dans la pratique, il suffit de ne pas en valeur la dispute.
C'est ce que je produis.
J'ai essayé de Igor version à l'aide de clés étrangères dans les deux tableaux sans les déclencheurs. Dans ce cas, cette contrainte n'est pas renvoyées.
J'obtiens cette erreur: ERREUR: la valeur null dans la colonne "address_id" viole non-nulle contrainte
Lors de l'insertion de l'utilisation de ce annonymous bloc:
Un autre problème avec l'application obligatoire de la participation dans member_details à l'aide de address_id de la table d'adresses (Igor version), c'est que cela me permet d'insérer une ligne dans member_details de référence et une adresse existante de la ligne, mais l'adresse existante ligne des références différentes member_details ligne. Lors de la dernière member_details ligne est supprimée en cascade et de supprimer l'adresse de ligne, ce qui peut ou ne peut pas le supprimer (dépend de la configuration) le nouveau inséré member_details ligne. Il serait également le retour d'informations différentes, lorsque le rejoindre sur member_id et sur address_id. Par conséquent, il nécessite une autre contrainte, alors je suis resté avec déclencheur et de le lâcher avant de l'insérer et de le recréer après l'insertion, en raison de la gâchette n'est pas reporté.