關於postgresql觸發器的總結(lab作業系列)

来源:https://www.cnblogs.com/northernmashiro/archive/2018/05/10/9004574.html
-Advertisement-
Play Games

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


上題:

  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的大套子,二三問和在一起寫個觸發器:

 1 create or replace function chk_car_rentals()
 2   returns trigger as $$
 3 begin
 4 if TG_OP='INSERT' then
 5   if (select count(*) from car_rentals
 6   where new.plate=plate and new.start_date <= end_date and new.end_date >= start_date
 7   group by plate) >0 then
 8     raise exception 'aaaaa';
 9     return null;
10   end if;
11 elsif TG_OP='UPDATE' then
12   if new.plate <> old.plate then
13     if (select count(*) from car_rentals
14     where new.plate=plate and new.start_date <= end_date and new.end_date >= start_date
15     group by plate) >0 then
16       raise exception 'aaaaa';
17       return null;
18     end if;
19   elsif new.start_date < old.start_date or new.end_date > old.end_date then
20     if (select count(*)
21         from (select * from car_rentals
22               except
23               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
24         where new.plate=plate and new.start_date <= end_date and new.end_date >= start_date
25         group by plate) >0 then
26       raise exception 'bbbb';
27       return null;
28     end if;
29   end if;
30 end if;
31 return new;
32 end;
33 $$ language plpgsql;
34 
35 create trigger trg_car_rental
36   before insert or update on car_rentals
37   for each row execute procedure chk_car_rentals();

 

--如果是Insert 語句,語句應該是插入的新日期在原日期之內且車牌號相等,導致插入的時間段重覆,引發異常
--如果是update 語句,當車牌號發生改變後,觸發觸發器的條件和上面 insert的條件相同,重覆將異常 
           當車牌號不變,利用except除去表中舊記錄的部分,select新的在所剩的表裡面看是否還存在著“撞車”的情況,把異常條件寫出來就好了


接下來就是測試這幾條insert,update語句,應和預期結果相同

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 日期轉化為字元串 (以2016年10月20日為例) select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') strDateTime from dual; --獲取年-月-日 時:分:秒 --顯示結果為:2016-10-20 12:35:21 select ...
  • 本文由 網易雲 發佈。 作者:郭憶 本篇文章僅限內部分享,如需轉載,請聯繫網易獲取授權。 故障恢復 MySQL基於Check point的機制,周期性的建立redo log與數據頁的一致點。一旦資料庫重啟,從記錄的Check point開始,根據redo log,對相應的數據頁進行更新,對於已經提交 ...
  • 通過數據交換平臺上傳較大的文件時,經常會出現導入失敗情況,換種方式通過新數據開發平臺(stark)也可以輕鬆實現外部數據與hive的數據關聯。 --第一步、導入csv文件到hive --stark數據開發平臺——>資源管理——>搜索欄右邊+號——>上傳資源(資源類型:選擇普通文件) --第二步、建表 ...
  • 本文由 網易雲 發佈。 作者:範欣欣 本篇文章僅限內部分享,如需轉載,請聯繫網易獲取授權。 眾所周知,HBase預設適用於寫多讀少的應用,正是依賴於它相當出色的寫入性能:一個100台RS的集群可以輕鬆地支撐每天10T 的寫入量。當然,為了支持更高吞吐量的寫入,HBase還在不斷地進行優化和修正,這篇 ...
  • 本文由 網易雲 發佈。 作者:唐雕龍 本篇文章僅限內部分享,如需轉載,請聯繫網易獲取授權。 面向新手的hadoop+hive學習環境搭建,加對我走過的坑總結,避免大家踩坑。 對於hive相關docker,並沒有官方的docker,第三方維護經過測試各種不靠譜,所以才想到自己搭建一套,然後後期在整理成 ...
  • 1. Flink的引入 這幾年大數據的飛速發展,出現了很多熱門的開源社區,其中著名的有 Hadoop、Storm,以及後來的 Spark,他們都有著各自專註的應用場景。Spark 掀開了記憶體計算的先河,也以記憶體為賭註,贏得了記憶體計算的飛速發展。Spark 的火熱或多或少的掩蓋了其他分散式計算的系統身 ...
  • 在使用cx_Oracle模塊讀取Oracle資料庫中的中文記錄時,返回值皆為?,後google得此佳文,遂問題得以解決,特此記之。 Oracle資料庫版本是10g,字元集是AL32UTF8. 編寫的python腳本中需要加入如下幾句: 這樣可以保證select出來的中文顯示沒有問題。 要能夠正常的i ...
  • 本篇介紹如何使用SSIS和作業完成自動更新目標數據任務。 ** 溫馨提示:如需轉載本文,請註明內容出處。** 本文連接:http://www.cnblogs.com/grom/p/9018978.html 筆者需要定期從伺服器更新N家客戶的遠程伺服器數據,上一篇的存儲過程是其中一個更新方法,後來隨著 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...