簡體   English   中英

與檢查約束中的另一個表相關嗎?

[英]Relate to another table in a check constraint?

假設我有一個名為Stock_item的表,並且包含一個名為Price的列。我有另一個表表示Purchase的列名為Buying_Price 。現在,我想為Price設置一個約束,以便Price> Buying_Price

您不能使用SQL約束來做到這一點。 檢查約束僅適用於單個表,外鍵僅強制執行相等性。

ANSI SQL標准包括一個稱為斷言的構造,該構造應該支持這種業務邏輯,但是沒有DBMS供應商實現它們。 他們很難有效地完成工作。

我們可以使用before插入或更新觸發器來模擬斷言。 像這樣:

  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是一種更好的方法。 至少將邏輯放入存儲的proc中,然后從觸發器中調用它。


“可以檢查價格> 0的約束”

哦,是的,這種驗證檢查約束適用於。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM