约束与触发器
完整性约束
删除/更新具有引用关系的表时,有以下操作:
1 | -- 被引用的行禁止删除 |
外键约束的几种方法:
方法1:
1 | create table so_headers( |
方法2:
1 | -- 创建表时,在末尾指定外键约束 |
方法3:
1 | -- 创建表时,在末尾指定外键约束,并且指定外键别名;so_id_fkey |
方法4:
1 | -- 修改表添加外键约束 |
DEFERRABLE
推迟约束
触发器
触发器(trigger)是用户定义在关系表上的由事件驱动调用函数的机制。
触发器比CHECK更灵活,可以实施各种复杂的检查和操作,具有更精细和更强大的数据保护能力。
在创建触发器之前,必须首先创建触发器函数,触发器函数的语法格式是:
1 | CREATE FUNCTION function_name() RETURNS TRIGGER AS $$ |
触发器中有两对前是函数头部。触发器函数定义的头部RETURNS后面只能是TRIGGER,并且触发器函数不能带任何参数。
两对$$之间是函数体。包括DECLARE部分的变量声明以及BEGIN和END之间的函数执行代码。DECLARE部分是可选的。
由于PG允许使用各种语言比如PL/pgSQL,C,Python来编写函数,所以第二对$$之后是对函数编写语言的说明。这里是PL/pgSQL。
触发器函数创建后,使用CREATE TRIGGER
命令创建触发器。
1 | CREATE TRIGGER name {BEFORE|AFTER} {event [OR...]} |
{event [OR…]}中,{}里面是一个或多个用OR分隔的事件列表。这里的事件包括数据库的数据修改操作,比如INSERT、DELETE或UPDATE等命令。
BEFORE|AFTER的意思是触发器可以分为BEFORE和AFTER触发器,分别在操作完成前和操作完成后执行触发器函数。
ON TABLE后面给出触发器所在表的表名。
触发器可以按行或按语句触发,也就是行级触发器和语句级触发器。
行级:[FOR [EACH] {ROW|STATEMENT}]
语句级:[FOR [EACH] {STATEMENT}]
行级触发器的触发器函数为触发语句影响的每一行执行一次。
语句级触发器的触发器函数为每条触发语句执行一次。
假设表examiner有10000行,定义了如下的UPDATE触发器:
1 | UPDATE examiner SET erage = erage + 1; |
如果是语句级触发器,则执行完该语句后,触发动作只发生1次;如果是行级触发器,则执行10000次。
触发器必须返回一个NULL或者一个元组类型的变量。
语句级触发器应返回NULL。
行级after触发器的值总是被忽略,可以返回null。
行级before触发器的返回值不同,对触发器操作的影响也不同。
如果返回NULL则忽略该触发器的行级操作,其后的触发器也不会执行。
如果返回非NULL,则返回的行将成为被插入或更新的行。
如果是行级触发器,可以在触发器函数中使用NEW和OLD引用UPDATE/INSERT事件之后的新值和UPDATE/DELETE事件之前的旧值。
插入examinee表的考号长度必须为10位:
创建触发器函数:
1 | CREATE FUNCTION examineeid() RETURNS TRIGGER AS $examineeid$ |
NEW代表INSERT或UPDATE操作产生的新的数据行
创建触发器:
1 | CREATE TRIGGER examineeid_insert BEFORE INSERT ON examinee |
三种:
1.DEFERRABLE INITIALLY DEFERRED
2.DEFERRABLE INITIALLY IMMEDIATE
3.NOT DEFERRABLE
1 | Copy"subject_iddddd" INTEGER REFERENCES "Subjects" ("id") DEFERRABLE INITIALLY IMMEDIATE |
注1:
IMMEDIATE
会在每一个语句执行后进行约束检查,DEFERRED
则只会在事务结束时才检查约束。(DEFERRED 只是推迟检查而不是不检查)注2:此设置仅影响 UNIQUE,PRIMARY KEY,REFERENCES (外键)和 EXCLUDE 约束
1 | SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE } |
注1:对 NOT DEFERRABLE
来说,SET CONSTRAINTS
不生效。
注2:SET CONSTRAINTS ALL
更改所有 DEFERRABLE 约束。
本文作者 : preccrep
原文链接 : https://preccrep.github.io/2021/05/10/%E7%BA%A6%E6%9D%9F%E4%B8%8E%E8%A7%A6%E5%8F%91%E5%99%A8/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!