上题:

  In this tutorial you will create a stored procedure and triggers to check a complex constraint. Consider the table definition below:

While the unique constraints defined here are sensible, they are not sufficient to express the constraint that a car (identified by its plate) cannot be rented more than once on any particular day.

1. Explain briefly why this constraint cannot be expressed using a CHECK constraint.

2. Write a stored procedure (function in postgres) which takes as input a plate, start date and end date and throws an error if table car rental contains any row with the same plate where the rental period is different from but overlaps with the given period. Note: Throwing errors in postgres is documented here: https://www.postgresql.org/docs/9.6/static/plpgsql-errors-and-messages.html Note: By checking only for different rental periods we don’t need to worry about the newly inserted or updated tuple using the procedure in a trigger (see next question). Duplicate periods are already prevented by the uniqueness constraints specified.

3.Create triggers which invoke the stored procedure created to enforce the “no duplicate rentals” constraint. Note: In postgres, trigger functions have no arguments and return type trigger: https://www.postgresql.org/docs/9.6/static/plpgsql-trigger.html Create a separate trigger function that meets these requirements and invokes the function defined earlier.

Note: You can test that your triggers work by inserting and updating tuples in car rentals:

-- should work
INSERT INTO car_rentals VALUES ('2-F4ST', '2015-02-02', '2015-02-11', 'DI123');
UPDATE car_rentals SET start_date = '2015-02-01', end_date = '2015-02-10';
INSERT INTO car_rentals VALUES ('SP33DY', '2015-01-20', '2015-02-05', 'DI234');
-- should fail (test individually)
UPDATE car_rentals SET plate = '2-F4ST' WHERE plate = 'SP33DY';
INSERT INTO car_rentals VALUES ('2-F4ST', '2015-02-10', '2015-02-15', 'DI234');
INSERT INTO car_rentals VALUES ('2-F4ST', '2015-01-20', '2015-02-15', 'DI234');
INSERT INTO car_rentals VALUES ('2-F4ST', '2015-02-02', '2015-02-09', 'DI234');
-- should work
INSERT INTO car_rentals VALUES ('2-F4ST', '2015-03-01', '2015-03-10', 'DI234');

-- additional test
update car_rentals set end_date = '2015-03-02' where plate = '2-F4ST' and license_nr='DI234'

第一问:check只能检测固定数值(给出来的值)进行约束,所以布恩能够用check,用触发器

首先是触发器,基本概念和用法:https://www.yiibai.com/postgresql/postgresql-trigger.html

建立一个触发器,首先先创造出对应函数,即你想让触发器完成什么样的工作,里面必须要有对条件的正确判断,begin开始,end结尾,外层套create的大套子,二三问和在一起写个触发器:

 create or replace function chk_car_rentals()
returns trigger as $$
begin
if TG_OP='INSERT' then
if (select count(*) from car_rentals
where new.plate=plate and new.start_date <= end_date and new.end_date >= start_date
group by plate) >0 then
raise exception 'aaaaa';
return null;
end if;
elsif TG_OP='UPDATE' then
if new.plate <> old.plate then
if (select count(*) from car_rentals
where new.plate=plate and new.start_date <= end_date and new.end_date >= start_date
group by plate) >0 then
raise exception 'aaaaa';
return null;
end if;
elsif new.start_date < old.start_date or new.end_date > old.end_date then
if (select count(*)
from (select * from car_rentals
except
select *from car_rentals where old.plate=plate and old.start_date=start_date and old.end_date=end_date and old.license_nr=license_nr) as new_car_rentals
where new.plate=plate and new.start_date <= end_date and new.end_date >= start_date
group by plate) >0 then
raise exception 'bbbb';
return null;
end if;
end if;
end if;
return new;
end;
$$ language plpgsql; create trigger trg_car_rental
before insert or update on car_rentals
for each row execute procedure chk_car_rentals();
--如果是Insert 语句,语句应该是插入的新日期在原日期之内且车牌号相等,导致插入的时间段重复,引发异常
--如果是update 语句,当车牌号发生改变后,触发触发器的条件和上面 insert的条件相同,重复将异常 
           当车牌号不变,利用except除去表中旧记录的部分,select新的在所剩的表里面看是否还存在着“撞车”的情况,把异常条件写出来就好了 接下来就是测试这几条insert,update语句,应和预期结果相同

关于postgresql触发器的总结(lab作业系列)的更多相关文章

  1. PostgreSQL触发器的使用

    原文: https://www.yiibai.com/postgresql/postgresql-trigger.html -------------------------------------- ...

  2. BCNF范式及其分解方法(对一次Lab作业的总结)

    BCNF是比第三范式更严格一个范式.它要求关系模型中所有的属性(包括主属性和非主属性)都不传递依赖于任何候选关键字.也就是说,当关系型表中功能上互相依赖的那些列的每一列都是一个候选关键字时候,该满足B ...

  3. CentOS7下载配置PostgreSQL的pgAgent运行代理作业

    1.安装PostgreSQL 参考官方文档https://www.postgresql.org/download/linux/redhat/,运行如下命令 yum install https://do ...

  4. postgresql 触发器

    一.创建事件触发器 1.ddl_command_start - 一个DDL开始执行前被触发: 2.ddl_command_end - 一个DLL 执行完成后被触发: 3.sql_drop -- 删除一 ...

  5. postgresql 触发器 更新操作

    1 前言 功能需求:当一张表格某个字段变化,另一张表某个字段写入该值 2 代码 CREATE OR REPLACE FUNCTION "public"."synStatu ...

  6. java数据结构和算法编程作业系列篇-数组

    /** * 编程作业 2.1 向highArray.java程序(清单2.3)的HighArray类添加一个名为getMax()的方法,它返回 数组中最大关键字的值,当数组为空时返回-1.向main( ...

  7. 触发器-- 肖敏_入门系列_数据库进阶 60、触发器(三) --youku

    二 https://v.youku.com/v_show/id_XMzkxOTc5NDY0OA==.html?spm=a2h0k.11417342.soresults.dtitle 三 https:/ ...

  8. SQL Server 创建作业系列问题

    一.从IClassFactory为CLSID为{AA40D1D6-CAEF-4A56-B9BB-D0D3DC976BA2}的COM组件创建实例失败. 尊重原著作:本文转载自http://www.hao ...

  9. Xquery的初步学习(一次Lab作业的总结)

    Task 1: Open countries.xml, compose the following XQueries: 1. Return the area of Mongolia. 2. Retur ...

随机推荐

  1. eclipse使用git命令行

    idea自带git命令,可以很方便的进行提交代码.eclipse怎么做呢,下面我简单操作一下: 第一步: 第二步: 第三步: 这样就调出来git提交的命令窗口了: 运行成功如下: 注意: git的安装 ...

  2. Sql Server tempdb原理-启动过程解析实践

    我们知道在SqlServer实例启动过程中数据库会进行还原(Redo,Undo)然后打开提供服务,但我们知道tempdb是不提供重做机制的(Redo)那tempdb是如何还原的呢?如果tempdb损坏 ...

  3. oracle数据泵备份(Expdp命令)

    Oracle备份方式主要分为数据泵导出备份.热备份与冷备份三种,今天首先来实践一下数据泵备份与还原.数据泵导出/导入属于逻辑备份,热备份与冷备份都属于物理备份.oracle10g开始推出了数据泵(ex ...

  4. The Go scheduler

    转载自:http://morsmachine.dk/go-scheduler Introduction One of the big features for Go 1.1 is the new sc ...

  5. MYSQL 5.7 sqlmode 行为

    最近碰到了sql_mode 的一些问题,故进行了研究,根据实际情况研究其行为. sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ER ...

  6. Winform 多个窗口编辑同一条数据同步的实现

    场景: 一个主窗口中,可以在列表(DataGridView)里选中一条记录编辑,打开一个编辑窗口(非模态窗口),编辑窗口保存后需要刷新父窗口,由于编辑窗口是非模态窗口,如果打开了多个窗口,并且都是编辑 ...

  7. RAC性能分析 - gc buffer busy acquire 等待事件

    概述---------------------gc buffer busy是RAC数据库中常见的等待事件,11g开始gc buffer  busy分为gc buffer busy acquire和gc ...

  8. Vue的路由

    Vue可以实现一种类是ajax不刷新但是切换界面 然后 只是在你的url中的当前地址后面追加信息 首先你要先当如这个路由的模块: <script src="https://unpkg. ...

  9. 上拉加载下拉刷新控件WaterRefreshLoadMoreView

    上拉加载下拉刷新控件WaterRefreshLoadMoreView 效果: 源码: // // SRSlimeView // @author SR // Modified by JunHan on ...

  10. sonarQube常见问题及分析

    阻断1.Close this"FileInputStream" in a "finally" clause.在finally中关闭FileInputStream ...