Sybase使用外键约束并对外表列值进行条件检查

时间:2012-03-07 17:11:04

标签: sql database sybase

Sybase是否可以定义一个约束,该约束要求列是外键并且还满足基于外来列的值的条件,例如:在下面的示例表中,可以在“product”表上创建约束,使得“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)
)

2 个答案:

答案 0 :(得分: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 :(得分: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

相关问题