psql-08表:触发器
语句级触发器与行为触发器
//创建一个对student表的操作记录表
create table log(
update_time timestamp, //操作时间
db_user varchar(40), //操作的数据库用户名
opr_type varchar(6) //操作类型
);
//创建触发器函数
create function log_trigger()
returns trigger as
$$
begin
insert into log values(now(), user, tg_op); //user即为当前用户名; to_op是触发器函数中的特殊变量,代表DML操作类型
return null;
end;
$$
language 'plpgsql';
- 语句级触发器:执行每个
SQL
时,只执行一次;
//创建一个语句级触发器
create trigger log_trigger
after insert or delete or update on student
for statement execute procedure log_trigger(); //statement
之后一个SQL语句无论是插入多条数据,删除多条数据或者更新删除不存在的数据;只要执行成功一个SQL语句,就会触发一次;
- 行级触发器: 以SQL语句操作后作用到的n行而触发n次;
create trigger log_trigger2
after insert or delete or update on student
for row execute procedure log_trigger();
before触发器和after触发器
- 语句级别的
before
触发器在语句开始做任何事情之前就触发; - 语句级别的
after
触发器在语句结束时触发; - 行级别的
before
触发器在特定进行操作之前触发; - 行级别的
after
触发器在语句结束时触发,但会在任何语句级别的after
触发器触发之前触发;
//before触发器可以直接修改new值以改变实际的更新值
create function student_new_name_trigger()
returns trigger as
' //$$
begin
new.student_name = new.student_name || new.student_no;
return new;
end;
' //$$
language 'plpgsql';
//
create trigger new_name_trigger
before insert or update on student
for each row execute procedure student_new_name_trigger();
//保存的数据student_name会变成要输入的值拼接上student_no
触发器的行为
- 触发器函数都有返回值;
- 语句级别的触发器总是返回
null
,即写为return null;
如果没有写会导致出错; - 行级
before
和instead of
这类行级触发器:
* 如果返回null
,则忽略对当前行的操作;
* 如果返回非null
的行,对insert,update
操作来说,返回的行为将成为插入或更新的行; - 行级
after
触发器,其返回值会被忽略; - 如果同一事件上有多个触发器,按触发器的名字顺序来触发;
- 对于行级
before
和instead of
这类行级触发器:
* 每个触发器返回的行将成为下一个触发器的输入;
* 返回内容为空的话,该行上其他行触发器也不会被触发;
事件触发器
- 用于弥补
PostgreSQL
以前版本不支持DDL
触发器功能;目前,其支持三种DDL
事件;
*ddl_command_start
: 一个DDL
开始执行前被触发;
*ddl_command_end
: 一个DDL
执行完之后被触发;
*sql_drop
: 删除一个数据库对象前被触发; - 由于事件触发器权限较大,所以只有超级用户才能创建修改事件触发器;
创建事件触发器
- 事件触发器函数的返回类型是
event_trigger
与普通触发器函数返回类型(trigger
)不同;
//一个禁止所有DDL语句的例子
create or replace function abort_any_command()
returns event_trigger
language plpgsql
as
$$
begin
raise exception 'command % is disabled', tg_tag;
end;
$$;
//
create event trigger abort_ddl on ddl_command_start
execute procedure abort_any_command();
//在postgresq中truncate事件是使用普通触发器触发的,事件触发器不会触发truncate table;
//禁止上面定义的事件触发器
alter event trigger abort_ddl disable;
- 可以从表
pg_evnet_trigger
中查看已经定义的触发器;
变量
- 事件触发器函数仅仅支持以下变量
tg_event
:为ddl_command_start,ddl_command_end,sql_drop
之一;tg_tag
: 具体的哪种DDL
操作,如:create table, drop table
等;
修改事件触发器
alter event trigger name [disable | enable];
alter event trigger name enable [replica | always];
alter event trigger name owner to new_owner;
alter event trigger name rename to new_name;
事件触发器记录数据库中对象删除的审计日志
//记录信息表
create table log_drop_objects (
op_time timestamp,
ddl_tag text,
classid oid,
objid oid,
objectsubid oid,
object_type text,
schme_name text,
object_name text,
object_identity text
);
//
create function event_trigger_log_drops()
returns event_trigger
language plpgsql as
$$
declare
obj record;
begin
insert into log_drop_objects select now(), tg_tag, classid, objid, objsubid, object_type,
schema_name, object_name, object_identity from pg_event_trigger_dropped_objects();
end
$$;
//
create event trigger event_trigger_log_drops
on sql_drop
execute procedure event_trigger_log_drops();
//创建一张测试表
create table test (id int primary key, note varchar(20));
//修改字段或删除表再查看记录表中的记录
alter table test drop column note;
表空间
- 表空间实际上是为表指定一个存储的目录;
- 创建数据库时可以为数据库指定默认的表空间;创建表和索引时可以指定表空间;
使用
- 创建:
create tablespace tablespace_name [owner user_name] location 'directory';
//
create tablespace tbs_data location '/data/pgdata';
- 创建数据库时指定
create database db01 set tablespace tbs_data;
- 改变数据库默认空间
//在此操作时保证没有其他人连接此数据库,否则会报错;
alter database db01 set tablespace tbs_data;
//数据中已经有的表的表空间不会改变;
- 建表的时候指定表空间
create table test01 (id int, note text) tablespace tbs_data;
- 创建索引时指定表空间
create index idx_test01_id on test01(id) tablespace tbs_data;
- 建唯一约束时可以指定约束索引的表空间
alter table test01 add constraint unique_test01_id unique(id) using index tablespace tbs_data;
- 增加主键时也可以指定主键索引的表空间
alter table test01 add constraint pk_test01_id primary key(id) using index tablespace tbs_data;
- 把表从一个空间移动到另一个表空间
//注意在移动表时候会锁表,此时所有对表的操作都会被阻塞;
alter table test01 set tablespace pg_default;
psql-08表:触发器的更多相关文章
- 数据库级别DML操作监控审计、表触发器/对象触发器
使用触发器记录DML,使用触发器记录表的DML 数据库级别DML操作监控审计.表触发器/对象触发器 --创建记录表 CREATE TABLE T_SHALL_LOG ( ID , ) , EVTIME ...
- [SQL]insert、update 表触发器应用的demo
--创建测试表 create table student ( stu_id int ,libraryCardNo varchar() ) create table borrowbook ( b_id ...
- TRIGGERS_监测系统_原始数据表触发器—调用告警信息存储过程
//每次向originaldata表中插入数据就会触发该触发器 create or replace trigger originaldata_to_alarm after insert on ori ...
- Sqlserver数据库 通过表触发器 实时通知应用程序
/* Sqlserver数据库开始相关服务 以下示例显示了如何查看 OLE Automation Procedures 的当前设置.0未启用 */ EXEC sp_configure 'show ad ...
- postgresql 表触发器
1.先建一个函数,用来执行触发器启动后要执行的脚本 CREATE OR REPLACE FUNCTION "public"."trigger_day_aqi"( ...
- Oracle生成多表触发器sql
--将所有HY开头的表都生成一个更新触发器的脚本('/'是为了连续创建多个触发器而不报错)select 'CREATE OR REPLACE TRIGGER '||table_name||' BEFO ...
- Oracle中根据表明获取对应表触发器名称
Select object_name From user_objects a left join all_triggers b on a.object_Name = b.trigger_name wh ...
- SQLSEVER 同台服务器下不同表 触发器实现数据实时同步
触发器的使用: 1.首先建立两个相同结构的表,两个表明的列的名称不同. student_01 字段 name ; 字段 age ; 字段 class ; student_02 字段 ...
- JS 08表单操作_表单域
一.表单的获取方式 document.getElementById() document.forms[index]; document.forms[form_name] document.form_n ...
随机推荐
- Samba服务器配置
Samba服务器配置流程: (1)安装samba服务器先用#rpm -ivh samba-列出与samba有关的rpm包然后选择第一个包,用tab键补齐文件名 (2)创建新用户和其密码#useradd ...
- log4Net控制台输出
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...
- Linux ip
工具/原料 linux系统 putty 方法/步骤 Linux下查看IP一般都是用命令在终端查看了,使用命令行来进行查看. 想要在图形界面查看的朋友也有办法,不过就比较复杂,不如一条命令来得痛 ...
- 在eclipse中遇到cannot open output file xxx.exe: Permission denied 的解决办法
该问题出现的原因主要原因是,编译后运行的程序未能正确关闭,解决方法:删除debug目录即可 同理在vc6.0遇到同样问题时,删除debug目录,或者重启vc6.0即可
- RSync实现文件备份同步
[rsync实现网站的备份,文件的同步,不同系统的文件的同步,如果是windows的话,需要windows版本cwrsync] 一.什么是rsync rsync,remote synchronize顾 ...
- thinkphp3.2与phpexcel基础生成
public function ff(){ import("Org.Util.PHPExcel"); import("Org.Util.PHPExcel.Workshee ...
- angularjs 中state.go 跳转并且打开新的浏览器窗口
包子最近遇到业务人员提的非常无厘头的需求,就是调页面的时候,一定要打开一个新的浏览器窗口...>o<奇葩!!! 但是我的页面都是state.go跳转的呀,我各种百度,发现,貌似state, ...
- c标签遍历List<Map<String, Object>> 数据格式
<c:forEach varStatus="loop" var="dataMap" items="${dataMap}"> &l ...
- 手动封装js原生XMLHttprequest异步请求
Code Object.extend =function(targetObj,fnJson){ //扩展方法,类似于jQuery的$.extend,可以扩展类的方法,也可以合并对象 for(var f ...
- Github.com上有哪些比较有趣的PHP项目?
链接就不贴了,可以在github上进行搜索.这里就不列举 symfony.laravel 这些大家都知道的项目了.只列举比较有意思的. swoole, C扩展实现的PHP异步并行网络通信框架,可以重新 ...