2012-03-07 15 views
1

Sybase有可能定義一個需要列作爲外鍵並滿足基於外列值的條件的約束,例如在下面的示例表中,可以在「產品」表上創建一個約束,使得「product.code是brand.code的外鍵,其有效值= 1」?帶外鍵的Sybase約束和針對外表列值的條件檢查

CREATE TABLE brand (
    code  char(8)  NOT NULL, 
    valid  int   NOT NULL, 
    rowid  numeric(10,0) IDENTITY, 
    CONSTRAINT brand_pk PRIMARY KEY (code), 
    CONSTRAINT valid_check CHECK (valid IN (0,1)) 
) 

CREATE TABLE product (
    code  char(8)  NOT NULL, 
    CONSTRAINT product_pk PRIMARY KEY (code) 
) 

回答

3

我認爲這是最好的改變結構只是一點點。

CREATE TABLE brand (
    code  char(8)  NOT NULL, 
    valid  int   NOT NULL, 
    rowid  numeric(10,0) IDENTITY, 
    CONSTRAINT brand_pk PRIMARY KEY (code), 

    -- The following UNIQUE constraint lets the pair of values be the target of 
    -- a foreign key reference. 
    CONSTRAINT brand_is_valid UNIQUE (code, valid), 

    CONSTRAINT valid_check CHECK (valid IN (0,1)) 
); 

CREATE TABLE product (
    code  char(8)  NOT NULL, 
    valid  int   NOT NULL, 

    -- The column "code" is a PK in the referenced table, so this still works. It's 
    -- a 1:0 or 1:1 relationship. 
    CONSTRAINT product_pk PRIMARY KEY (code), 

    -- The next constraint requires a unique constraint on the pair of 
    -- columns in the table "brand". By itself, it references every row 
    -- in "brand". That's too many rows. 
    CONSTRAINT product_fk FOREIGN KEY (code, valid) 
          REFERENCES brand (code, valid), 

    -- But this constraint restricts the foreign key references to only those 
    -- rows that have valid = 1 in the table "brand". 
    CHECK (valid = 1) 
); 
1

爲了繞過基於「有效」條件的外鍵的創建,你將需要修改表的設計和創建觸發器設置product.code = NULL。請原諒我的語法(我沒有對Sybase編碼一段時間),但這是一般想法:

添加一個新列作爲主鍵,因爲我們需要在有效時設置product.code = NULL = 0:

CREATE TABLE product (
    rowid  int identity primary key, 
    code  char(8) NULL, 
    CONSTRAINT brand_fk FOREIGN KEY (code) REFERENCES brand(code) 
) 

然後創建類似這樣的觸發:

create trigger FK_WhenValid 
on product 
for insert 
AS 
    IF (SELECT COUNT(*) FROM brand b inner join inserted i on b.code = i.code AND b.valid=0) > 0 
    BEGIN 
    UPDATE product SET code = NULL WHERE code in (SELECT i.code from brand b join inserted i on b.code = i.code and b.valid = 0) 
    END 

注:此觸發器只支持產品插入。如果「有效」可以改變,則需要另一種方法。

你也可以實現外鍵作爲觸發而不是聲明約束,只設置product.code = inserted.code時有效= 1