PostgreSQL 规则简介 - 创建不可修改的条目
来自 PostgreSQL Wiki
跳转到导航跳转到搜索作者:Justin Clift
简介
你试过 PostgreSQL 的“规则”吗?如果你还没有,你可能会喜欢这个快速实用的介绍,你可能会马上用上它!
PostgreSQL 规则用于在查询执行之前拦截和更改查询。例如,假设你有一个表格,人们可以在其中添加内容,但你需要在表格中添加 3 个永远不能修改或删除的条目。这就是你该怎么做。
让我们创建一个示例表格
foo=> CREATE TABLE gift_certificates (idnum serial, person varchar(20), amount float4); NOTICE: CREATE TABLE will create implicit sequence 'gift_certificates_idnum_seq' for SERIAL column 'gift_certificates.idnum' NOTICE: CREATE TABLE/UNIQUE will create implicit index 'gift_certificates_idnum_key' for table 'gift_certificates' CREATE
让我们给它一些数据
foo=> insert into gift_certificates (person, amount) values ('Justin', 200); INSERT 51564057 1 foo=> insert into gift_certificates (person, amount) values ('Tom', 200); INSERT 51564059 1 foo=> insert into gift_certificates (person, amount) values ('Richard', 200); INSERT 51564062 1 foo=> insert into gift_certificates (person, amount) values ('Peter', 200); INSERT 51564065 1 foo=> insert into gift_certificates (person, amount) values ('Bruce', 200); INSERT 51564066 1 foo=> insert into gift_certificates (person, amount) values ('Marc', 200); INSERT 51564067 1 foo=> insert into gift_certificates (person, amount) values ('Vince', 200); foo=> select * from gift_certificates; idnum | person | amount -------+---------+-------- 1 | Justin | 200 2 | Tom | 200 3 | Richard | 200 4 | Peter | 200 5 | Bruce | 200 6 | Marc | 200 7 | Vince | 200 (7 rows)
在这个例子中,你将创建两个规则
foo=> CREATE RULE prot_gc_upd AS ON UPDATE TO gift_certificates WHERE old.idnum < 4 DO INSTEAD nothing; CREATE foo=> CREATE RULE prot_gc_del AS ON DELETE TO gift_certificates WHERE old.idnum < 4 DO INSTEAD nothing; CREATE
“nothing” 子句是合法的 PostgreSQL 规则子句,它有效地删除了 SQL 查询会更新 gift_certificates 表中前 3 个条目中的任何一个的操作。不过,在该表上运行的所有 SQL 查询都将完美运行(除了那些试图更新或删除前 3 个条目中的任何一个的查询)。
出于兴趣,WHERE 子句可以是任何标准的 SQL WHERE 子句。这个例子还添加了 “old” 关键字到 idnum 字段。 “old.idnum” 字段的意思是“在尝试查询开始之前存在的 idnum 版本”。阅读手册了解更多信息。:)
现在,让我们测试一下
foo=> update gift_certificates set person = 'Justin2' where idnum = 1; UPDATE 0 foo=> update gift_certificates set person = 'Justin2' where idnum = 2; UPDATE 0 foo=> update gift_certificates set person = 'Justin2' where idnum = 3; UPDATE 0 foo=> update gift_certificates set person = 'Justin2' where idnum = 4; UPDATE 1
看看最后一次更新是如何工作的,因为它没有受到 PostgreSQL 规则的保护?
foo=> select * from gift_certificates; idnum | person | amount -------+---------+-------- 1 | Justin | 200 2 | Tom | 200 3 | Richard | 200 5 | Bruce | 200 6 | Marc | 200 7 | Vince | 200 4 | Justin2 | 200 (7 rows) foo=>
上面的删除规则也起作用了
foo=> delete from gift_certificates; DELETE 4 foo=> select * from gift_certificates; idnum | person | amount -------+---------+-------- 1 | Justin | 200 2 | Tom | 200 3 | Richard | 200 (3 rows) foo=>
很酷吧?
希望你发现它有用!
有关 PostgreSQL 规则的更多信息,请参考 PostgreSQL 程序员指南,“"PostgreSQL 规则系统"”。