2015-04-14 8 views
1

У меня проблема с внедрением БД. У меня есть 2 таблицы:Oracle SQL, условный внешний ключ

CREATE TABLE TAB1 
(
    TAB1_ID INT NOT NULL PRIMARY KEY, 
    TAB1_BOOL VARCHAR(4) NOT NULL CHECK (TAB1_BOOL IN('OPT1', 'OPT2')) 
); 
CREATE TABLE TAB2 
(
    TAB2_ID INT NOT NULL 
); 

Я хотел бы сделать TAB2_ID в качестве внешнего ключа TAB1_ID, но TAB2_ID может быть только эти TAB1_IDs, какие строки в таблице TAB1 выделены TAB1_BOOL == OPT1. Например:

TAB1 contains 2 rows: 
1. 'TAB1_ID==1' 'TAB1_BOOL==OPT1', 
2. 'TAB1_ID==2' 'TAB1_BOOL==OPT2'. 
Now, statement like: 
INSERT INTO TAB2 (TAB2_ID) VALUES (2); 
should be rejected because row with TAB1_ID==2 is marked with OPT2 

Возможно ли это сделать в Oracle SQL?

+0

Вы пытались определить внешний ключ? BTW, какая версия Oracle? – jarlh

+0

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production, у меня нет проблем с определением внешнего ключа. Посмотрите на пример – devPash

+0

Подзапросы в пределах ограничений проверки не разрешены в базе данных оракула, вы можете реализовать триггер для него. – jfun

ответ

1

Это может быть достигнуто с помощью триггера:

CREATE TABLE TAB1 (
    TAB1_ID INT NOT NULL PRIMARY KEY, 
    TAB1_BOOL VARCHAR(4) NOT NULL CHECK (TAB1_BOOL IN('OPT1', 'OPT2')) 
); 

CREATE TABLE TAB2 (
    TAB2_ID INT NOT NULL, 
    FOREIGN KEY (TAB2_ID) REFERENCES TAB1 (TAB1_ID) 
); 

CREATE OR REPLACE TRIGGER CHECK_TAB2_ID 
    BEFORE UPDATE OR INSERT ON TAB2 FOR EACH ROW 
DECLARE 
    CURSOR CHECK_CURSOR IS 
     SELECT TAB1_BOOL 
      FROM TAB1 
     WHERE TAB1_ID = :new.TAB2_id; 
    V_TAB1_BOOL VARCHAR(4); 
BEGIN 
    OPEN CHECK_CURSOR; 
    FETCH CHECK_CURSOR INTO V_TAB1_BOOL; 
    IF (V_TAB1_BOOL <> 'OPT1') THEN 
     CLOSE CHECK_CURSOR; 
     raise_application_error(10000, 'Wrong value in TAB1'); 
    END IF; 
    CLOSE CHECK_CURSOR; 
END; 

INSERT INTO TAB1 VALUES (1, 'OPT1'); 
INSERT INTO TAB1 VALUES (2, 'OPT2'); 

INSERT INTO TAB2 (TAB2_ID) VALUES (1); 

Существует еще небольшая ошибка в приведенном выше триггера. У меня нет доступа к базе данных Oracle, поэтому я могу это исправить. Вот мой Fiddle.

p.s.: ok, только ; отсутствует в Fiddle - here's обновление.

+0

Ницца, спасибо! – devPash

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