使用MySQL CHECK确保表中的值与其他表匹配

时间:2012-01-22 20:23:47

标签: mysql sql constraints

我希望我的一个表检查以确保输入其中一个字段的值是正确的。

就我而言,我有一个名为Book的表,还有一个名为Sale的表。由于每次销售都有一本书的isbn,我应该可以确保在Sale表中输入的价格与Book表中与isbn相对应的价格相匹配。我确信我应该在SQL中使用CHECK约束,但我不知道该怎么做。

父表:

CREATE TABLE Book
(
    isbn INTEGER NOT NULL,
    title VARCHAR(20),
    author VARCHAR(20),
    price DOUBLE,
    PRIMARY KEY (isbn)
);

INSERT进入Book表:

INSERT INTO Book
VALUES (1, 'A Separate Peace', 'John Knowles' 9.99);

我的孩子表:

CREATE TABLE Sale
(
    date DATE,
    saleId INTEGER NOT NULL,
    isbn INTEGER,
    price DOUBLE,
    PRIMARY KEY (saleId),
    FOREIGN KEY (isbn) REFERENCES Book (isbn),
    CHECK (price = (Book (price) WHERE Book (isbn) = isbn))
);

销售的INSERT语句示例:

INSERT INTO Sale 
VALUES ('2012-01-01', 1234, 1, 8.99);

请注意,正确的价格是9.99,而不是8.99。我希望这个INSERT返回错误。

3 个答案:

答案 0 :(得分:2)

您应该在系统的软件部分实现这种业务逻辑。

  • 当您想要提供折扣或何时提供产品时,怎么样?
  • 如果销售让1年前的Book1为9.99,一年之后同一本书的价格会变为8.99,该怎么办?

如果您不想这样,那么没有理由将价格保存两次(在两个表中),因此只需从Sales表中删除price列,并在从数据库中读取时使用isbn no来确定产品价格。

答案 1 :(得分:1)

假设价格可能会发生变化,并且您希望将当前的图书价格设为Book.price,而以Sale.price出售图​​书的价格。

要确保插入到表格Sale中的价格是当前图书价格(存储在Book中),而不是:

INSERT INTO Sale 
  VALUES ('2012-01-01', 1234, 1, 8.99) ;

你可以使用这样的东西:

INSERT INTO Sale 
  SELECT '2012-01-01', 1234, isbn, price
  FROM Book
  WHERE isbn = 1 ;

答案 2 :(得分:0)

是的@ypercube的解决方案将实现您想要的,但这违背了最佳做法和database normalization

如果是这种情况,那么我们还应该在sales表中为名称,作者等添加更多列。

我建议您将业务逻辑分开并保持简单,除非您真的必须这样做。