0

我想修改以下 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

4 回答 4

0

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

如果您真的想实施这种检查,我想您将不得不使用触发器。

请注意,您已经为 work-at 和 manages 建模了多对多关系。如果它是多对一的,它本来是可行的,因为它看起来像 Employee(number, name,works_at_store_code, manages_store_code)。并且约束将只是检查(manages_store_code 为空或 manages_store_code =works_at_store_code)。

于 2013-06-20T16:30:06.140 回答
0

我看到了一些选项,尽管实现取决于 RDBMS:

  • 检查调用函数/存储过程的约束。
  • 触发器或自定义存储过程。
  • 使用插入选择语法

检查调用函数的约束

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

示例/来源:

自定义存储过程/函数

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

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

将插入与选择一起使用

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

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
于 2013-06-20T16:31:33.303 回答
0

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

drop table manages;

alter table works_at
add column isManager bit default 0;

如其他答案中所述,确保每家商店都存放每种产品最好使用触发器。

您还应该考虑以下几点。

  1. char(5) 不一定是主键字段的最佳数据类型
  2. 将员工编号作为主键可能不是一个好主意。在现实生活中可能会有调动,或者有人可能在不止一家商店兼职。
  3. 如果每家商店都应该储存每件商品,那么stocks 表可能就没有用了。包含现有数量的库存表可能会更好。
于 2013-06-20T16:38:45.693 回答
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)
  )

关于您的第二部分,我看不到强制执行库存必须包含所有商店和所有产品这一事实的方法,这似乎也毫无意义,您实际上是在要求一个只是交叉连接的表另外两张桌子。

于 2013-06-20T16:46:14.597 回答