与检查约束中的另一个表相关联?

时间:2015-03-22 06:34:11

标签: sql oracle

假设我有一个名为 Stock_item 的表格,它包含一个名为价格的列。我有另一个表格购买,其中包含一列名为 Buying_Price 。现在我想为价格设置约束,以便价格> Buying_Price

1 个答案:

答案 0 :(得分:3)

您无法使用SQL约束来执行此操作。检查约束仅适用于单个表,外键仅强制执行相等。

ANSI SQL标准包含一个名为Assertions的构造,它应该支持这种业务逻辑,但没有DBMS供应商实现它们。他们有效地做事非常棘手。

我们可以使用before insert或update触发器来模拟断言。像这样:

  create or replace trigger stock_item_price
  before insert or update on stock_item
  for each row
  declare
       l_buy_price purchase.buying_price%type;
  begin
      select p.buying_price
      into l_buy_price
      from purchase p
      where p.item_code = :new.item_code;

      if l_buy_price <= :new.price 
      then
          raise_application_error(-20000
           , 'Price must exceed Buying_Price');
  end;

这有几点需要注意。因为它会针对每一行触发,所以在批量更新方案中效率非常低。它可能无法在多用户环境中工作(例如,如果有人对PURCHASE进行了未提交的更改)。并且它不会以其他方式执行任何操作;如果有人增加了BUYING_PRICE,那么这个触发器就会被激活。所以也许你需要购买另一个触发器。但这可能并不可取。

正如您所看到的,触发器是一种执行应用程序逻辑的混乱方式,尤其是因为它们很容易被忽视。程序API是一种更好的方法。至少将逻辑放在存储过程中并从触发器中调用它。


  

&#34;可以检查比如Price&gt; 0&#34;

哦,是的,那种验证检查约束适用于。

alter table stock_item 
     add constraint stock_item_price_chk 
         check ( Price > 0 )
/