J'ai une table avec une plage de dates de début, une plage de dates de fin et quelques autres colonnes supplémentaires. Lors de la saisie d'un nouvel enregistrement, je souhaite ajuster automatiquement toutes les plages de dates qui se chevauchent (les réduire, les diviser ou les supprimer pour tenir compte de la nouvelle entrée - voir l'algorithme ci-dessous). Je veux également m'assurer qu'aucun enregistrement qui se chevauche ne peut être accidentellement inséré dans cette table. J'utilise Oracle et Java pour mon code d'application. Comment devrais-je appliquer la prévention des plages de dates qui se chevauchent et permettre également d'ajuster automatiquement les plages de chevauchement? Dois-je créer un déclencheur AFTER INSERT, avec un dbms_lock pour sérialiser l'accès, pour empêcher le chevauchement des données. Puis en Java, appliquer la logique pour tout ajuster automatiquement? Ou cette partie doit-elle être en PL/SQL dans l'appel de procédure stockée? C'est quelque chose dont nous avons besoin pour quelques autres tables, donc ce serait bien de faire abstraction.Table de plage de réglage automatique
Si quelqu'un a quelque chose comme cela déjà écrit, s'il vous plaît partager :)
Je ne trouve cette référence: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:474221407101
Voici un exemple de savoir comment traiter chacun des 4 cas de chevauchement pour le réglage à l'insertion :
= Example 1 =
In DB (Start, End, Value):
(0, 10, 'X')
**(30, 100, 'Z')
(200, 500, 'Y')
Input
(20, 50, 'A')
Gives
(0, 10, 'X')
**(20, 50, 'A')
**(51, 100, 'Z')
(200, 500, 'Y')
= Example 2 =
In DB (Start, End, Value):
(0, 10, 'X')
**(30, 100, 'Z')
(200, 500, 'Y')
Input
(40, 80, 'A')
Gives
(0, 10, 'X')
**(30, 39, 'Z')
**(40, 80, 'A')
**(81, 100, 'Z')
(200, 500, 'Y')
= Example 3 =
In DB (Start, End, Value):
(0, 10, 'X')
**(30, 100, 'Z')
(200, 500, 'Y')
Input
(50, 120, 'A')
Gives
(0, 10, 'X')
**(30, 49, 'Z')
**(50, 120, 'A')
(200, 500, 'Y')
= Example 4 =
In DB (Start, End, Value):
(0, 10, 'X')
**(30, 100, 'Z')
(200, 500, 'Y')
Input
(20, 120, 'A')
Gives
(0, 10, 'X')
**(20, 120, 'A')
(200, 500, 'Y')
L'algorithme est la suivante:
given range = g; input range = i; output range set = o
if i.start <= g.start
if i.end >= g.end
o_1 = i
else
o_1 = i
o_2 = (i.end + 1, g.end)
else
if i.end >= g.end
o_1 = (g.start, i.start - 1)
o_2 = i
else
o_1 = (g.start, i.start - 1)
o_2 = i
o_3 = (i.end + 1, g.end)
@Adam: +1, bien que je définirais la clé primaire comme '(start_at)' de sorte que vous n'ayez aucune ambiguïté avec deux périodes commençant en même temps. Le compromis d'un tel modèle est également qu'il est plus difficile d'interroger que le modèle avec '(start, end)'. –
Ma compréhension (et limitée) était que chaque clé avait ses propres gammes. Cela semble être correct, et de même, l'OP semble avoir des plages indéfinies. Si tel est le cas, l'OP doit également insérer (START_AT, VALUE) des enregistrements de fencepost (: previous_logical_end + 1, NULL). La suggestion de vue matérialisée était d'aider avec la question de question, bien que je ne pense pas qu'interroger la table de base elle-même est si mauvais, particulièrement pas avec l'analytique. Modification de la réponse –
Adam, merci pour votre réponse. Je n'ai pas pensé à une telle solution. Avant votre suggestion, le modèle de données ressemble à quelque chose comme (product_id, start_date, end_date, discount_value). J'ai besoin d'obtenir le discount_value pour un produit sur une date. L'utilisateur saisit la date de début et de fin de l'exécution de la remise pour un produit, ainsi que le montant de la remise. Mon exemple spécifique est un peu plus compliqué, donc j'espère que l'exemple de produit/rabais est une représentation juste de mon problème. Oui, il existe des plages indéfinies. – Bradford