2014-12-24 3 views
0

У меня есть следующие таблицы.Ссылочная адресата

ACCOUNTS (Родительская таблица) с столбцами как ACC_ID, VALID_FROM и VALID_TO с уникальным ключом по ACC_ID, VALID_FROM.

ACCOUNT_BUSII_FUNCTIONS (таблица детей) с столбцами как ACC_ID, BUSINESS_FUNCTION, VALID_FROM и VALID_TO с уникальным ключом по ACC_ID, BUSINESS_FUNCTION, VALID_FROM.

VALID_FROM и VALID_TO - это даты.

Мне нужно построить отношения, в которых каждая запись, удаленная в ACCOUNTS (родительская таблица), должна проверять, чтобы дочерняя запись падала в том же диапазоне дат. Аналогично, перед вставкой в ​​дочерний элемент проверьте, существует ли родитель с допустимым диапазоном дат.

Очевидно, что я не могу использовать ограничения внешнего ключа, поскольку задействованы диапазоны дат.

Пробовал записывать функцию и вызывать ограничение CHECK, но не работал, поскольку ограничение CHECK не разрешало определять пользовательскую функцию.

Am невежественны ... любая помощь, пожалуйста ...

Приветствия TZH

+2

* «Очевидно, что я не могу использовать ограничения внешнего ключа, поскольку задействованы диапазоны дат». * Диапазоны дат * не связаны с ключевыми ограничениями. «VALID_FROM» - дата; это не диапазон. Нет причин, чтобы ограничение внешнего ключа не срабатывало * в отношении dbms *. Если есть причина * бизнеса *, внешний ключ, включая «VALID_FROM», не будет работать, отредактируйте свой вопрос и сделайте это более понятным. –

+0

@ MikeSherrill'CatRecall '- Кажется, дочерние записи могут попадать в диапазон допустимости родительской записи: границы не должны совпадать. – APC

ответ

0

Я думаю, спусковые будет лучшим выбором, чем функции. Попробуйте что-нибудь вроде:

CREATE TRIGGER ACCOUNTS_BD 
    BEFORE DELETE ON ACCOUNTS 
    FOR EACH ROW 
DECLARE 
    nChild_rows NUMBER: 
BEGIN 
    SELECT COUNT(*) 
    INTO nChild_rows 
    FROM ACCOUNT_BUSII_FUNCTIONS a 
    WHERE a.ACC_ID = :OLD.ACC_ID AND 
      (:OLD.VALID_FROM BETWEEN a.VALID_FROM AND a.VALID_TO OR 
      :OLD.VALID_TO BETWEEN a.VALID_FROM AND a.VALID_TO OR 
      a.VALID_FROM BETWEEN :OLD.VALID_FROM AND :OLD.VALID_TO OR 
      a.VALID_TO BETWEEN :OLD.VALID_FROM AND :OLD.VALID_TO); 

    IF nChild_rows > 0 THEN 
    RAISE_APPLICATION_ERROR(-20001, 'Child rows found when deleting from ACCOUNTS'); 
    END IF; 
END ACCOUNTS_BD; 

CREATE TRIGGER ACCOUNT_BUSII_FUNCTIONS_BI 
    BEFORE INSERT ON ACCOUNT_BUSII_FUNCTIONS 
    FOR EACH ROW 
DECLARE 
    nParent_rows NUMBER; 
BEGIN 
    SELECT COUNT(*) 
    INTO nParent_rows 
    FROM ACCOUNTS a 
    WHERE a.ACC_ID = :NEW.ACC_ID AND 
      (:NEW.VALID_FROM BETWEEN a.VALID_FROM AND a.VALID_TO OR 
      :NEW.VALID_TO BETWEEN a.VALID_FROM AND a.VALID_TO OR 
      a.VALID_FROM BETWEEN :NEW.VALID_FROM AND :NEW.VALID_TO OR 
      a.VALID_TO BETWEEN :NEW.VALID_FROM AND :NEW.VALID_TO); 

    IF nParent_rows = 0 THEN 
    RAISE_APPLICATION_ERROR(-20002, 'No parent row found when inserting into ' || 
            'ACCOUNT_BUSII_FUNCTIONS'); 
    END IF; 
END ACCOUNT_BUSII_FUNCTIONS_BI; 

Не проверено на животных - вы будете первыми! :-)

Делитесь и наслаждайтесь.

+0

Привет, Это отлично работает. Отлично. Спасибо за ответ. – TZH

Смежные вопросы