表a的外來鍵,一定是其他某個表b的主鍵或有unique宣告的屬性。
a的外來鍵的值,一定是對應表b中相應的屬性值。(空值除外)
方法1:屬性名 型別 references 表名 (屬性名)
方法2:foreign key (屬性名) reference 表名 (屬性名)
createtable
studio(
name
char(30) primary
key,
address
varchar(255
), persc#
intreferences
movieexec(cert#)
);
createtable
studio(
name
char(30) primary
key,
address
varchar(255
), presc#
int,
foreign
key (persc#) references
movieexec(cert#)
);
設表a的外來鍵,是表b的主鍵或unique。
則,下面的四種情況出錯:
1.a中插入的新元組(非空值),其外來鍵不是b中的值
2.a中修改的新元組(非空值),其外來鍵不是b中的值
3.刪除b中的元組,其主鍵非空,且是a的外來鍵
4.修改b中的元組的主鍵,且是a的外來鍵
其中1,2一定不能違反。3,4可以有3種處理方法:
1.預設原則:拒絕違反更新。
2.級聯原則:如果把b中的主鍵刪除,則刪除對應a中的元組;如果修改b中的主鍵,也修改a中相應的外來鍵
3.置空值原則:如果對b的主鍵的修改,影響到了a中的外來鍵,則把a中的相應外來鍵置空。
宣告方法:
on delete或on update後面加上set null或cascade
createtable
studio(
name
char(30) primary
key,
address
varchar(255
), presc#
intreferences
movieexec(cert#)
ondelete
setnull
onupdate
cascade
);
上面語句表示,刪除時採用置空值原則,更新時採用級聯原則。
如果有迴圈約束,比如表a, b。a是外來鍵,引用b;且b是外來鍵,引用a。則這是乙個迴圈約束。不管以怎樣的順序插入都會違反外來鍵約束。解決方法:
1.將兩個插入動作組成乙個事務
2.通知dbms不用檢查其約束,直到整個事務完成執行並要提交為止。
為做到第2點,可以使用如下語句:
約束後面加:deferrable(延遲)或not deferrable(非延遲 預設)
deferrble後面可以有initially deferred(檢查推遲到事務提交前執行),initially immediate(立即執行檢查 ??跟not deferrable區別??)
如果約束有名字,如myconstraint可以用
set constraint myconstraint deferred; 設為延遲檢查
set constraint myconstraint immediate; 設為立即檢查
createtable
studio(
name
char(30) primary
key,
address
varchar(255
), persc#
intunique
references
movieexec(cert#)
deferrable initially deferred
);
①非空值約束:不允許該屬性為空值。方法:在create table的屬性宣告後面用not null
persc# intreferences movieexec(cert#) not
null
注意:會導致外來鍵約束中的置空原則不可用。
②基於屬性的check約束
presc# intreferences
movieexec(cert#)
check (presc# >=
100000)
上述語句保證presc#至少有6位
gender char(1) check (gender in ('f', '
m'))
上述語句保證gender只能取『f』,『m』兩種情況。
presc# intcheck
(presc#
in (select cert# from movieexec))
上述語句跟前面的外來鍵約束很像,但是有不同。
不同點:1.該語句使得presc#不能為空,而外鍵約束可以(置空值原則) 2.該檢查只在插入時起作用,但是後面對presc#修改導致違反該約束時,該約束無法檢查出來。(這樣的效率高,如果要嚴謹則不要這麼寫)
涉及元組的多個屬性的約束,要用基於元組的約束。
例,禁止把乙個男性male的名稱以ms.開頭。
則check中的應該是 非(male && ms.) = 非(male) or 非(ms.)
createtable
moviestar(
name
char(30) primary
key,
address
varchar(255
), gender
char(1
), birthdate date,
check (gender ='f
'or name not
like
'ms.%')
);
與基於屬性的check約束相比,基於元組的check約束檢查的更頻繁,只要該元組的任乙個屬性被改變,都要檢查。而基於屬性的check約束只有在相應的屬性變化時才檢查。
SQL 觸發器 外來鍵約束
1 構造乙個觸發器audit log,在向employees test表中插入一條資料的時候,觸發插入相關的資料到audit中。create table employees test id int primary key not null,name text not null,age int not...
SQL觸發器例項1
sql觸發器例項1 定義 何為觸發器?在sql server裡面也就是對某乙個表的一定的操作,觸發某種條件,從而執行的一段程式。觸發器是乙個特殊的儲存過程。常見的觸發器有三種 分別應用於insert update delete 事件。我為什麼要使用觸發器?比如,這麼兩個表 create table ...
SQL觸發器例項1
定義 何為觸發器?在sql server 裡面也就是對某乙個表的一定的操作,觸發某種條件,從而執行的一段程式。觸發器是乙個特殊的儲存過程。常見的觸發器有三種 分別應用於 insert update delete 事件。為什麼要使用觸發器?比如,這麼兩個表 create table student 學...