2013-04-25 44 views
1

這可能不是一個很好的問題,與DB結構及其混紡的業務邏輯,但它不是我的決定,讓一個值不能大於另一個定義一個約束的推斷一個列的值(表A,列X)不能大於另一個(表B,柱Y)的通過外鍵所引用的值時:SQL約束,在不同的表

TABLE_A 
    ID (Primary Key) 
    X (int value) 
TABLE_B 
    A_ID (Foreign Key to TABLE_A) 
    Y (int value) 

即我想強制執行Y的所有值,Y < L其中L是來自X的值,其中TABLE_B.A_ID == TABLE_A.ID

我正在使用DB2。

回答

2

是否有可能定義一個約束的推斷一個列的值(表A,列X)不能大於另一個(表B,柱Y)的通過外鍵所引用的值時:

不需要。這需要在CHECK約束中使用SELECT語句,而DB2不支持該語句。如果確實支持使用SELECT語句的,它看起來像這樣。

ALTER TABLE_B 
ADD CONSTRAINT TABLE_B_Y_LT_L 
CHECK (Y < (SELECT X FROM TABLE_A WHERE TABLE_A.ID = TABLE_B.A_ID)); 

由於TABLE_A.ID是唯一的,所以SELECT語句將返回單個值。但是,正如我所說的,DB2不支持檢查約束中的SELECT語句。我不認爲目前的任何dbms都可以。

解決辦法

有幾個解決方法。首先,你可以寫一個觸發器。其次,您可以在兩個表中存儲列「X」,並使用外鍵約束和檢查約束來實現您的要求。

-- Since "id" is unique, the combination of "id" and "x" is also unique. 
-- Declaring "unique (id, x)" lets these two columns be the target of a 
-- foreign key reference. 
-- 
create table table_a (
    id integer primary key, 
    x integer not null, 
    unique (id, x) 
); 

-- The foreign key references both columns in "table_a". The check constraint 
-- indirectly guarantees that y < table_a.x. 
-- 
create table table_b (
    a_id integer not null, 
    a_x integer not null, 
    y integer not null, 
    primary key (a_id, a_x, y), 
    foreign key (a_id, a_x) references table_a (id, x), 
    check (y < a_x) 
); 

這是標準的SQL。它應該可以在任何當前的SQL DBMS中工作。