[英]Sybase constraint with foreign key and conditional check against foreign table column value
Is it possible on Sybase to define a constraint(s) which require a column to be a foreign key and also satisfy a condition based on the value of a foreign column, eg in the below example tables could a constraint be created on the "product" table such that "product.code is a foreign key of a brand.code which has valid=1"? 是否可以在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)
)
I think it's best to change the structure just a little bit. 我认为最好稍微改变结构。
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)
);
In order to bypass the creation of a foreign-key based on the "valid" condition, you will need to modify your table design and create a trigger to set the product.code = NULL. 为了绕过基于“有效”条件的外键创建,您需要修改表设计并创建触发器以设置product.code = NULL。 Pardon my syntax (I haven't coded Sybase for a while), but this is the general idea:
请原谅我的语法(我有一段时间没有编写Sybase),但这是一般的想法:
Add a new column to serve as the primary key since we will need to set product.code = NULL when valid=0: 添加一个新列作为主键,因为我们需要在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)
)
Then create a trigger similar to this one: 然后创建一个类似于这个的触发器:
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
Note: this trigger only supports product insertions.
注意:此触发器仅支持产品插入。 If "valid" can change, another approach is required.
如果“有效”可以改变,则需要另一种方法。
You could also implement the foreign key as a trigger instead of a declarative constraint and only set product.code = inserted.code when valid = 1 您还可以将外键实现为触发器而不是声明性约束,并且仅在valid = 1时设置product.code = inserted.code
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.