簡體   English   中英

Sybase使用外鍵約束並對外表列值進行條件檢查

[英]Sybase constraint with foreign key and conditional check against foreign table column value

是否可以在Sybase上定義一個約束,該約束要求列為外鍵並且還滿足基於外部列的值的條件,例如,在下面的示例表中,可以在“產品”上創建約束“table表示”product.code是具有有效值= 1“的brand.code的外鍵?

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)
)

我認為最好稍微改變結構。

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)
);

為了繞過基於“有效”條件的外鍵創建,您需要修改表設計並創建觸發器以設置product.code = NULL。 請原諒我的語法(我有一段時間沒有編寫Sybase),但這是一般的想法:

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

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

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

您還可以將外鍵實現為觸發器而不是聲明性約束,並且僅在valid = 1時設置product.code = inserted.code

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM