1
votes

Contraintes de vérification des bases de données relationnelles ORACLE

Je travaille sur un projet pour Uni et je n'ai pas beaucoup de connaissances ou d'expérience avec les bases de données. J'essaie de créer une base de données dans Oracle avec une table contenant des pièces fabriquées pouvant être de 2 types, disons 1 et 2. Quand la pièce est de type 1, je vais stocker dans la table son emplacement, quand elle est de type 2 I stockera dans la même table le délai de livraison. Ainsi, j'aurai des valeurs nulles pour l'autre colonne dans les deux cas (je suis conscient des problèmes avec les valeurs nulles, mais après y avoir réfléchi et recherché quelle est la meilleure façon de gérer cela, j'ai décidé de le faire comme ça, car je n'ai qu'une petite quantité d'attributs). Mon problème est dans le CHECK CONSTRAINT. J'ai essayé de le faire de cette façon:

insert into manufactured(PID, PARTTYPE, LEAD_TIME) VALUES (102, 2, '2 WEEKS');

Cela ne fonctionne pas.

J'ai essayé d'insérer un enregistrement comme suit:

insert into manufactured values (101,1,'Warehouse1');


3 commentaires

Que signifie «ne fonctionne pas»? Pour les questions sur le code, donnez un exemple reproductible minimal PS Une contrainte échoue lorsqu'elle est évaluée à false, sinon elle est satisfaite.


Cela aide, mais ce n'est toujours pas un exemple reproductible minimal . Par exemple, vous ne dites pas ce que vous pensez que cela fait, vous donnez simplement un code erroné. Par exemple, vous ne donnez pas de code copier-coller et exécutable. Par exemple, votre code n'est pas minimal - il a beaucoup d'erreurs, vous n'avez pas commencé avec le plus petit code qui fonctionne auquel vous avez ajouté une plus petite erreur. PS Lorsque vous recevez un message d'erreur, recherchez le manuel et le Web et vérifiez votre code pour tous les cas qu'il couvre.


Options de conception pour le sous-typage: Comment pouvez-vous représenter l'héritage dans une base de données? (etc.)


3 Réponses :


0
votes

Je ne sais pas quel SGBDR vous utilisez. Par exemple, dans Oracle, la contrainte CHECK accepte les valeurs nulles.

Comme je le vois, il existe différents attributs / types de données pour chaque type de parti. Il existe deux approches:

  1. divise les données en deux tableaux distincts. Dans cette solution, certains déclencheurs peuvent être nécessaires.
    • tab1: fabriqué_1 (attributs + contraintes pour PID 1)
    • tab2: fabriqué_2 (attributs + contraintes pour PID 2)
  2. utilisez le déclencheur "après insertion / mise à jour" - il définira les données inutiles sur null. Par exemple, si dans le tableau sera l'heure pour PID = 1, le déclencheur définira la valeur de l'heure sur null.

0 commentaires

1
votes

Cette instruction d'insertion:

insérer dans fabriqué (PID, PARTTYPE, LOCATION) valeurs (101,1, 'Entrepôt1');

... échoue car votre contrainte LEADTIME nécessite que PARTTYPE = 2 . (C'est une condition AND , donc si PARTTYPE = 1 la contrainte échouera quelle que soit la valeur de LEAD_TIME .)

C'est ce que je pense que vous cherchez:

CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
--CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
--CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL OR PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
--CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
--CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT LEADTIME CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL OR PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));

En gros, faites une contrainte sur chaque colonne qui applique l'ensemble de la logique pour cette colonne.

Si vous voulez vraiment deux contraintes sur chaque colonne, vous pouvez le faire aussi. Si tel est le cas, postez un commentaire et je mettrai à jour cette réponse. Je ne veux pas encombrer / confondre le problème autrement.


2 commentaires

Je n'ai pas besoin de le faire avec 2 contraintes pour la colonne, je ne savais tout simplement pas comment le faire. Mais c'était exactement ce dont j'avais besoin! Merci beaucoup!


@Mary - lorsque vous recevez une réponse utile, veuillez la voter et / ou l'accepter comme si c'était la meilleure réponse. Les votes positifs et les acceptations augmentent la valeur de ce site pour les futurs chercheurs.



0
votes
  • L'erreur ORA-00947: pas assez de valeurs pour

    insérer dans les valeurs fabriquées (101,1, 'Warehouse1'); est évident,

    car la dernière colonne ( lead_time ) de la table ( fabriqué ) est manquante pour la liste des valeurs .

  • Les erreurs ORA-02290: vérifier la contrainte proviennent du dépendant conditions parmi les contraintes de contrôle LEADTIME et LEADTIME2 , ceux-ci doivent être combinés comme
    CONTRAINTEZ LE CONTRÔLE DU TEMPS D'ÉCHÉANCE ((PARTTYPE = 2 ET LEAD_TIME N'EST PAS NUL) OU (PARTTYPE = 1 ET LEAD_TIME EST NULL)) .

  • La même logique fonctionne également pour les contraintes LOC et LOC2 qui devraient produire

    CONTRAINTEZ LOC CHECK ((PARTTYPE = 1 AND LOCATION IS NOT NULL) OU (PARTTYPE = 2 AND LOCATION IS NULL))


0 commentaires