2016-06-07 1 views
0

besoin de votre aideCheck Constraint dans Oracle SQL Developer

J'ai une table dans Oracle SQL Developer de ce genre:

 
Issue 
ID|Subscriber_ID|Book_ID| Taken |Returned 
--+-------------+-------+--------+-------- 
1 | 1   | 2 |01-06-16|05-06-16 
2 | 3   | 5 |07-05-16| (null) 
3 | 2   | 2 |06-06-16| (null) 
4 | 1   | 3 |17-05-16|26-05-16 

Il est une sorte de délivrance de livres bibliothèque où (null) dans des moyens de colonnes utilisées que ce livre n'a pas encore été rendu. J'ai besoin de créer une règle de validation pour éviter d'émettre un livre qui n'a pas été retourné (par exemple je ne peux pas prendre le livre # 5 pour le moment). Comment puis-je l'implémenter?

+0

Vous ne pouvez pas. Pas comme une contrainte. Vous pouvez créer une fonction/procédure pour le faire. Une contrainte ne peut pas être créée pour vérifier les lignes précédentes. Est-ce qu'une fonction vous sert? –

Répondre

1

Hmmm. Vous ne pouvez pas le faire avec une contrainte check, car ceux-ci ne s'appliquent qu'aux valeurs d'une ligne.

Ce que vous voulez vous assurer, c'est que vous n'avez pas deux valeurs retournées pour un livre. Certaines bases de données prennent en charge les index uniques filtrés:

create unique index on unq_issue_bookid on issue(book_id) where returned is null; 

Mais pas Oracle. Vous pouvez faire quelque chose de très similaire avec un indice basé sur les fonctions:

create unique index on unq_issue_bookid_returned 
    on issue(book_id, 
      (case when returned is not null then id else -1 end) 
      ); 

Cela aura le même effet de permettre à une seule NULL valeur par livre.

0

Vous pouvez le faire avec:

CREATE TABLE table_name (ID, Subscriber_ID, Book_ID, Taken, Returned) AS 
SELECT 1, 1, 2, DATE '2016-06-01', DATE '2016-06-05' FROM DUAL UNION ALL 
SELECT 2, 3, 5, DATE '2016-05-07', NULL FROM DUAL UNION ALL 
SELECT 3, 2, 2, DATE '2016-06-06', NULL FROM DUAL UNION ALL 
SELECT 4, 1, 3, DATE '2016-05-17', DATE '2016-05-26' FROM DUAL; 

ALTER TABLE table_name ADD is_borrowed 
    GENERATED ALWAYS AS (CASE WHEN returned IS NULL THEN 1 END) VIRTUAL; 

ALTER TABLE TABLE_NAME ADD CONSTRAINT is_borrowed__u 
    UNIQUE(book_id, is_borrowed); 

Puis:

INSERT INTO table_name (ID, Subscriber_ID, Book_ID, Taken) 
VALUES (5, 2, 5, DATE '2016-06-06'); 

échouera avec:

SQL Error: ORA-00001: unique constraint (TEST.IS_BORROWED__U) violated 
+0

Merci, mais cette solution ne fonctionne pas car lorsque le livre a été retourné une fois que vous ne pouvez plus le retourner (pair (book_id, null) doit être unique aussi) – JGDger