简体   繁体   中英

Relate to another table in a check constraint?

假设我有一个名为Stock_item的表,并且包含一个名为Price的列。我有另一个表表示Purchase的列名为Buying_Price 。现在,我想为Price设置一个约束,以便Price> Buying_Price

You can't do this using SQL constraints. Check constraints only work on a single table and foreign keys only enforce equality.

The ANSI SQL standards include a construct called Assertions which are supposed to support this sort of business logic but no DBMS vendor has implemented them. They're pretty tricky to do efficiently.

We can simulate assertions with a before insert or update trigger. Something like this:

  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;

This comes with several caveats. Because it fires for each row it would be pretty inefficient in a bulk update scenario. It might not work in a multi-user environment (say if somebody has uncommitted changes to PURCHASE). And it won't enforce anything in the other way; if somebody increases the BUYING_PRICE this trigger won't fire. So maybe you need another trigger on PURCHASE. But that might not be desirable.

As you can see, triggers are a messy way of enforcing application logic, not least because they are easily overlooked. A procedural API is would be a better approach. At the very least put the logic in stored procs and call it from a trigger.


"can a check contraint like Price > 0"

Oh yes, that the sort of validation check constraints are for.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM