添加CHECK以对多个表施加约束

时间:2013-06-20 16:25:06

标签: sql sqlanywhere

我想修改以下DDL以添加CHECK约束,以便商店的经理在同一商店工作,而商店提供所有产品,如果其类型为“本地”。

有人可以帮忙吗?

CREATE TABLE employee(
  employee_number CHAR(5) NOT NULL,
  name VARCHAR(30),
  store_code CHAR(5)
  PRIMARY KEY(employee_number),
  FOREIGN KEY(store_code) REFERENCES store
  )

CREATE TABLE store(
  store_code CHAR(5) NOT NULL,
  type VARCHAR(15),
  employee_number CHAR(5),
  PRIMARY KEY(store_code),
  FOREIGN KEY(employee_number) REFERENCES employee
  )


CREATE TABLE product(
  product_code CHAR(5) NOT NULL,
  description VARCHAR(150),
  cost DEC(10,2),
  PRIMARY KEY(product_code)
  )

CREATE TABLE stocks(
  store_code CHAR(5) NOT NULL,
  product_code CHAR(5) NOT NULL,
  PRIMARY KEY(product_code, store_code),
  FOREIGN KEY(product_key) REFERENCES product,
  FOREIGN KEY(store_code) REFERENCES store
  )

4 个答案:

答案 0 :(得分:0)

CHECK约束仅限于单个表中的单个行。

如果你真的想要实施这种检查,我猜你必须使用触发器。

请注意,您已为工作和管理建立了多对多关系。如果它是多对一的,它本来是可行的,因为它看起来像Employee(number,name,works_at_store_code,manages_store_code)。约束只是CHECK(manages_store_code为null或manages_store_code = works_at_store_code)。

答案 1 :(得分:0)

我看到的选项虽然实现的变化取决于RDBMS:

  • 检查约束调用函数/存储过程。
  • 触发器或自定义存储过程。
  • 使用insert-select语法

检查约束调用函数

您必须创建函数,然后在创建约束时使用它。

实例/来源:

自定义存储过程/功能

除了提议的触发器解决方案之外,另一个选择是创建用于插入数据的存储过程。

存储过程执行验证,如果不满足条件则不插入数据。

使用Insert with Select

以下内容将确保除非员工在特定商店工作,否则不会添加管理条目。

INSERT INTO manager (emploee_number, store_code) AS
SELECT distinct employee_number,
       store_code
FROM manages
WHERE store_code = INPUT_STORE_CODE
  AND employee_number = INPUT_EMPLOYEE_NUMBER

答案 2 :(得分:0)

为确保经理真正在商店工作,我会这样做:

drop table manages;

alter table works_at
add column isManager bit default 0;

如其他答案中所述,确保每个商店都能最好地使用触发器来完成每件商品。

您还应该考虑以下几点。

  1. char(5)不一定是主键字段的最佳数据类型
  2. 将员工编号作为主键可能不是一个好主意。在现实生活中,可能会有转移,或者有人可能在不止一家商店兼职工作。
  3. 如果每个商店都应该存放每个商品,那么库存表可能没用。包含库存数量的库存表可能更好。

答案 3 :(得分:0)

您可以通过更改works_at中的主键,然后添加唯一约束来确保唯一性。这比使用检查约束要好:

CREATE TABLE works_at(
  employee_number CHAR(5),
  store_code CHAR(5),
  PRIMARY KEY(employee_number, store_code),
  FOREIGN KEY(employee_number) REFERENCES employee,
  FOREIGN KEY(store_code) REFERENCES store,
  CONSTRAINT UQ_Works_at_employee_number UNIQUE NONCLUSTERED(employee_number) -- ENSURES EMPLOYEE CAN ONLY WORK AT ONE STORE
  )

然后,您的manages表格可以引用works_at,以确保他们管理所在的商店:

CREATE TABLE manages(
  employee_number CHAR(5),
  store_code CHAR(5),
  PRIMARY KEY(store_code),
  FOREIGN KEY(employee_number, store_code) REFERENCES works_at (employee_number, store_code)
  )

关于你的第二部分,我没有看到一种强制执行股票必须包含所有商店和所有产品这一事实的方法,这看起来似乎毫无意义,你本质上要求一张只是一张桌子另外两个表的交叉连接。

相关问题