กลับไปหน้าบทความ

อ่าน 8 นาที

ไม่มีชื่อบทความ

ท ริกเกอร์ฐานข้อมูล คือ โค้ดขั้นตอน ที่ดำเนินการโดยอัตโนมัติเพื่อตอบสนองต่อ เหตุการณ์ เฉพาะ บน ตาราง หรือ มุมมอง ใน ฐานข้อมูล ทริกเกอร์มักใช้เพื่อรักษา ความสมบูรณ์ ของข้อมูล...

ทริกเกอร์ฐานข้อมูล

ริกเกอร์ฐานข้อมูลคือโค้ดขั้นตอนที่ดำเนินการโดยอัตโนมัติเพื่อตอบสนองต่อเหตุการณ์ เฉพาะ บนตารางหรือมุมมองในฐานข้อมูลทริกเกอร์มักใช้เพื่อรักษาความสมบูรณ์ ของข้อมูล ภายในฐานข้อมูล ตัวอย่างเช่น การแทรกบันทึกพนักงานใหม่สามารถสร้างรายการที่เกี่ยวข้องในตารางภาษี วันหยุด และเงินเดือนโดยอัตโนมัติ ในทำนองเดียวกัน ทริกเกอร์ช่วยให้สามารถบันทึกข้อมูลในอดีตได้ เช่น การติดตามค่าใช้จ่ายสำหรับเงินเดือนพนักงานเมื่อเวลาผ่านไป[ 1 ]

ทริกเกอร์ในระบบจัดการฐานข้อมูล (DBMS)

ด้านล่างนี้คือภาพรวมของวิธีการที่ ระบบจัดการ ฐานข้อมูล (DBMS) ทั่วไปหลายระบบ รองรับทริกเกอร์

ออราเคิล

นอกเหนือจาก ทริกเกอร์ ภาษาการจัดการข้อมูลมาตรฐาน (DML)ที่เรียกใช้ โค้ด PL/SQLเมื่อมีการแก้ไขข้อมูลแล้วOracleยังรองรับทริกเกอร์ที่ทำงานเมื่อมีการเปลี่ยนแปลงระดับสคีมาและเหตุการณ์ฐานข้อมูลทั่วทั้งระบบ ทั้งทริกเกอร์ภาษาการกำหนดข้อมูลระดับสคีมา(DDL)และทริกเกอร์เหตุการณ์ระบบได้รับการแนะนำพร้อมกันในOracle 8i [ 2 ] [ 3 ]

ทริกเกอร์ระดับสคีมา

  • BEFORE CREATE
  • AFTER CREATE
  • BEFORE ALTER
  • AFTER ALTER
  • BEFORE DROP
  • AFTER DROP

การทำงานของทริกเกอร์ DML มาตรฐานของ Oracle นั้นถูกกำหนดโดยระดับความละเอียด (ความถี่ในการทำงานของทริกเกอร์) และการกรองเหตุการณ์ (การเปลี่ยนแปลงเฉพาะใดที่จะกระตุ้นการทำงาน):

โดยระดับความละเอียด

  • ระดับแถว: ทริก เกอร์จะทำงานหนึ่งครั้งสำหรับแต่ละแถวที่ได้รับผลกระทบจาก คำสั่ง INSERT , UPDATEหรือDELETE (ที่กำหนดโดยใช้FOR EACH ROWเงื่อนไข) หากคำสั่งแก้ไขห้าสิบแถว ทริกเกอร์จะทำงานห้าสิบครั้ง
  • ระดับคำสั่ง:ดำเนินการเพียงครั้งเดียวสำหรับ คำสั่ง SQL ทั้งหมด โดยไม่คำนึงถึงจำนวนแถวที่ถูกแก้ไข (พฤติกรรมเริ่มต้นหรือกำหนดโดยใช้FOR EACH STATEMENT) จะทำงานแม้ว่าจะไม่มีแถวใดได้รับผลกระทบจากการดำเนินการก็ตาม

โดยการกรองเหตุการณ์

  • ระดับตาราง:เปิดใช้งานกับการดำเนินการมาตรฐานใดๆINSERTที่UPDATEกำหนดDELETEเป้าหมายไปยังตารางทั้งหมด
  • ระดับคอลัมน์:ตัวกรองพิเศษที่ใช้กับUPDATEทริกเกอร์ ซึ่งจำกัดการทำงานให้ทำงานเฉพาะเมื่อมีการแก้ไขคอลัมน์ที่ระบุชื่อไว้เท่านั้น (กำหนดโดยใช้UPDATE OF column_nameไวยากรณ์)

ทริกเกอร์ระดับสคีมาและระดับระบบ

  • ทริกเกอร์ระดับสคีมา (DDL):ทำงานเมื่อมีการเปลี่ยนแปลงอ็อบเจ็กต์สคีมาผ่านคำสั่งต่างๆ เช่นAFTER, CREATE, BEFORE ALTER, หรือAFTER DROP.
  • ทริกเกอร์ระดับระบบ : ทำงานเพื่อตอบสนองต่อเหตุการณ์ฐานข้อมูลเชิงปฏิบัติการ รวมถึงการเข้าสู่ระบบของผู้ใช้ ผู้ใช้LOGOFFฐานข้อมูลSTARTUPและฐานSHUTDOWNข้อมูล[ 4 ]

ไมโครซอฟต์ SQL Server

Microsoft SQL Server รองรับทริกเกอร์สำหรับคำสั่ง DML และ DDL รวมถึงทริกเกอร์พิเศษ "การเข้าสู่ระบบ" ด้วย

ขอบเขตของทริกเกอร์ DDL สามารถเป็นฐานข้อมูลเดียวCREATE TRIGGER...ON DATABASEหรืออินสแตนซ์ SQL Server ทั้งหมดก็ได้CREATE TRIGGER...ON ALL SERVERเมื่อกำหนดค่าสำหรับอินสแตนซ์ทั้งหมด ทริกเกอร์จะตรวจจับทั้งเหตุการณ์ระดับเซิร์ฟเวอร์และระดับฐานข้อมูลที่ดำเนินการภายในอินสแตนซ์นั้น

รายการเหตุการณ์การเรียกใช้งานทริกเกอร์ DDL ที่มีอยู่ทั้งหมดมีอยู่ในเอกสารอย่างเป็นทางการของ Microsoft [ 5 ]

ทริกเกอร์ DDL ใน SQL Server สามารถครอบคลุมฐานข้อมูลเดียวหรือทั้งอินสแตนซ์ได้ สำหรับการดำเนินการ DML จะใช้ตารางเสมือน insertedและdeletedในขณะที่ทริกเกอร์ทำงานในระดับคำสั่ง แต่สามารถใช้ตรรกะระดับแถวได้ผ่านเคอร์เซอร์

โพสต์เกรสซีอาร์

PostgreSQLเพิ่มการรองรับทริกเกอร์ในปี 1997 ต่อมาได้รวมทริกเกอร์เฉพาะคอลัมน์ในเวอร์ชัน 9.0 ซึ่งสอดคล้องกับมาตรฐานSQL:2003 อย่างสมบูรณ์ [ 6 ]ในขณะที่ทริกเกอร์ DML มาตรฐานจะผูกกับตารางเฉพาะ การแก้ไขสคีมาที่ไม่ใช่ DML เช่นCREATE TABLEจะถูกบันทึกทั่วโลกในระดับฐานข้อมูลโดยทริกเกอร์เหตุการณ์ ซึ่งเป็นคุณสมบัติที่แนะนำใน PostgreSQL 9.3 [ 7 ]

ไวยากรณ์ SQL พื้นฐานสำหรับการกำหนดทริกเกอร์ใน PostgreSQL มีโครงสร้างดังนี้:

สร้างทริกเกอร์name { ก่อน| หลัง} { เหตุการณ์[ หรือ... ] } บนtable_name [ สำหรับ[ แต่ละ] { แถว| คำสั่ง} ] เรียกใช้โปรซีเดอร์funcname ( อาร์กิวเมนต์)

นกไฟ

Firebirdรองรับทริกเกอร์ระดับแถวหลายตัวต่อตารางสำหรับ การดำเนินการ INSERT, UPDATE, และDELETEรวมถึงการรวมกันของการกระทำเหล่านี้ ทริกเกอร์เหล่านี้จะทำงานก่อนหรือหลังการแก้ไขข้อมูล และทำงานเพิ่มเติมจากการเปลี่ยนแปลงตารางเริ่มต้น ผู้ใช้สามารถระบุลำดับการทำงานของทริกเกอร์หลายตัวที่สัมพันธ์กันได้โดยใช้POSITIONข้อความ ทริกเกอร์ยังสามารถกำหนดบนวิวเป็นINSTEAD OFทริกเกอร์ ซึ่งจะแทนที่ตรรกะของวิวที่สามารถอัปเดตได้เริ่มต้น ก่อนเวอร์ชัน 2.1 ทริกเกอร์บนวิวที่สามารถอัปเดตได้จะทำงานเพิ่มเติมจากตรรกะของเอนจินเริ่มต้น แทนที่จะแทนที่[ 8 ]

โดยค่าเริ่มต้น เอ็นจินฐานข้อมูลอนุญาตให้ทริกเกอร์ซ้อนกันและเรียกซ้ำได้ และจะไม่สร้างข้อยกเว้นตารางที่เปลี่ยนแปลงข้อมูล Firebird ใช้ ตัวแปรบริบท NEWและOLDเพื่อเข้าถึงสถานะของแถวในระหว่างการแก้ไขข้อมูล นอกจากนี้ยังให้แฟล็กบริบทแบบบูลีนINSERTING, UPDATING, และDELETINGแฟล็กเพื่อระบุเหตุการณ์ DML เฉพาะที่เริ่มต้นการทำงานของทริกเกอร์โดยใช้โปรแกรม

{ สร้าง| สร้างใหม่| สร้างหรือแก้ไข} ชื่อทริกเกอร์สำหรับ{ ชื่อตาราง| ชื่อวิว} [ ใช้งาน| ไม่ใช้งาน] { ก่อน| หลัง} { แทรก[ หรืออัปเดต] [ หรือลบ] | อัปเดต[ หรือแทรก] [ หรือลบ] | ลบ[ หรืออัปเดต] [ หรือแทรก] } [ ตำแหน่งn ] เริ่มต้น.... สิ้นสุด

ตั้งแต่เวอร์ชัน 2.1 เป็นต้นไป Firebird ได้เพิ่มการรองรับทริกเกอร์ระดับฐานข้อมูล ซึ่งจะทำงานเมื่อเกิดเหตุการณ์เฉพาะในเซสชันและธุรกรรม ตัวอย่างเช่น เหตุการณ์การเชื่อมต่อ ผ่านท ริกเกอร์ CONNECTและDISCONNECTและเหตุการณ์ธุรกรรม ผ่าน ทริกเกอร์ TRANSACTION START, TRANSACTION COMMIT, และ TRANSACTION ROLLBACKหากเกิดข้อยกเว้นระหว่างCONNECTทริกเกอร์ ลำดับการเชื่อมต่อจะถูกยกเลิก ในทำนองเดียวกัน ข้อยกเว้นที่เกิดขึ้นภายในทTRANSACTION COMMITริกเกอร์จะขัดขวางการดำเนินการธุรกรรมให้เสร็จสมบูรณ์ รวมถึงขั้นตอนการเตรียมการระหว่างการยืนยันแบบสองขั้นตอน

ทริกเกอร์ระดับฐานข้อมูลสามารถใช้เพื่อบังคับใช้ข้อจำกัดหลายตารางหรือเพื่อจำลองมุมมองที่สร้างขึ้นเมื่อเกิดข้อยกเว้นภายในTRANSACTION COMMITทริกเกอร์ การแก้ไขธุรกรรมที่ทำโดยทริกเกอร์ก่อนเกิดข้อผิดพลาดจะถูกยกเลิก และแอปพลิเคชันไคลเอ็นต์จะได้รับแจ้ง อย่างไรก็ตาม ธุรกรรมนั้นยังคงทำงานอยู่ราวกับว่าCOMMITการดำเนินการไม่เคยเริ่มต้น ทำให้แอปพลิเคชันสามารถทำการแก้ไขข้อมูลเพิ่มเติมและร้องขอลำดับการยืนยันได้[ 9 ]

รูปแบบไวยากรณ์ทั่วไปสำหรับการสร้างหรือแก้ไขทริกเกอร์ระดับฐานข้อมูลใน Firebird มีโครงสร้างดังต่อไปนี้:

{ สร้าง| สร้างใหม่| สร้างหรือแก้ไข} ชื่อทริกเกอร์[ ใช้งาน| ไม่ทำงาน] เมื่อ{ เชื่อมต่อ| ตัดการเชื่อม ต่อ | เริ่ม ธุรกรรม | ยืนยันธุรกรรม| ยกเลิกธุรกรรม} [ ตำแหน่งn ] เริ่มต้น..... สิ้นสุด

MySQL/MariaDB

ทริกเกอร์ MySQL/MariaDB ซึ่งเปิดตัวในปี 2548 (เวอร์ชัน 5.0) รองรับเหตุการณ์ DML โดย MySQL 8.0 อนุญาตให้ใช้ทริกเกอร์ประเภทเดียวกันได้หลายตัว แม้ว่าทริกเกอร์ DDL จะไม่ได้รับการสนับสนุนก็ตาม[ 10 ]ไวยากรณ์ที่เข้ากันได้กับทั้งสองระบบใช้ , CREATE TRIGGER, DROP TRIGGERและ สำหรับการ ดำเนินFOR EACH ROWการระดับแถว โดยมีเนื้อหาเริ่มต้นด้วยSETหรือBEGIN[ 11 ]

IBM DB2 LUW

IBM Db2 สำหรับLinux , UnixและWindows (Db2 สำหรับ LUW) รองรับทริกเกอร์หลักสามประเภทที่จำแนกตามเวลาการเปิดใช้งาน ได้แก่BEFORE, AFTER, และINSTEAD OFเอนจินรองรับทั้งความละเอียดระดับแถวและระดับคำสั่ง หากมีการกำหนดทริกเกอร์หลายตัวสำหรับการดำเนินการเดียวกันบนตารางเดียว ลำดับการดำเนินการจะถูกกำหนดตามลำดับโดยประทับเวลาการสร้าง ตั้งแต่เวอร์ชัน 9.7 เป็นต้นไป Db2 ยังรองรับธุรกรรมอิสระ ทำให้ทริกเกอร์สามารถดำเนินการธุรกรรมอิสระที่สามารถยืนยันหรือยกเลิกได้โดยไม่ส่งผลกระทบต่อคำสั่งที่ทำให้เกิดทริกเกอร์[ 12 ]

BEFOREริกเกอร์ใช้เพื่อตรวจสอบความถูกต้องของข้อมูลที่เข้ามาและพิจารณาว่าควรอนุญาตให้มีการแก้ไขข้อมูลหรือไม่ หากเกิดข้อยกเว้นภายในBEFOREทริกเกอร์ การดำเนินการจะถูกยกเลิกและการเปลี่ยนแปลงในฐานข้อมูลจะถูกย้อนกลับ แม้ว่าBEFOREทริกเกอร์จะไม่สามารถดำเนินการคำสั่ง DML เพื่อแก้ไขตารางฐานข้อมูลโดยตรงได้ แต่ก็ไม่ได้เป็นแบบอ่านอย่างเดียวโดยสมบูรณ์ ทริกเกอร์สามารถแก้ไขสถานะข้อมูลที่เข้ามาได้โดยใช้โปรแกรม โดยการเปลี่ยนแปลงค่าเป้าหมายภายในตัวแปรการเปลี่ยนผ่านของแถวก่อนที่จะเขียนลงดิสก์[ 13 ]

ในทางกลับกันAFTERทริกเกอร์จะทำงานหลังจากที่การแก้ไขข้อมูลที่ร้องขอเสร็จสมบูรณ์ แตกต่างจากBEFOREทริกเกอร์ทั่วไปAFTERทริกเกอร์สามารถดำเนินการเขียนข้อมูลแบบ DML ต่อไปได้ในตารางฐานข้อมูลใดๆ รวมถึงตารางที่ใช้งานอยู่ซึ่งเป็นตัวเริ่มต้นการทำงานของทริกเกอร์ ทINSTEAD OFริกเกอร์ใช้กับวิวโดยเฉพาะเพื่อแทนที่ตรรกะการประมวลผลเริ่มต้นและทำให้วิวที่ไม่สามารถอัปเดตได้สามารถเขียนได้ ตรรกะเชิงกระบวนการภายในทริกเกอร์ของ Db2 มักเขียนโดยใช้ส่วนขยายภาษาเชิงกระบวนการSQL PL

ฐานข้อมูล SQLite

สร้างทริกเกอร์[ ชั่วคราว| ชั่วคราว] [ ถ้ายังไม่มีอยู่] [ ชื่อฐานข้อมูล.] ชื่อทริกเกอร์[ ก่อน| หลัง| แทนที่] { ลบ| แทรก| อัปเดต[ ของชื่อคอลัมน์[, ชื่อคอลัมน์]...] } บน{ ชื่อตาราง| ชื่อวิว} [ สำหรับแต่ละแถว] [ เมื่อเงื่อนไข] เริ่มต้น... สิ้นสุด

SQLiteรองรับเฉพาะทริกเกอร์ระดับแถวเท่านั้น และไม่มีระบบรองรับทริกเกอร์ระดับคำสั่งโดยตรง

มุมมองที่สามารถอัปเดตได้ ซึ่งโดยปกติแล้วเอนจินจะไม่รองรับนั้น สามารถจำลองได้โดยการใช้INSTEAD OFทริกเกอร์กับโครงสร้างมุมมองเป้าหมาย

ฐานข้อมูล XML

ทริกเกอร์ถูกนำไปใช้ในระบบจัดการฐานข้อมูลที่ไม่ใช่เชิงสัมพันธ์ ตัวอย่างเช่น ฐานข้อมูล XML อย่าง Sednaรองรับทริกเกอร์ที่ใช้XQueryทริกเกอร์ใน Sedna ถูกออกแบบมาให้เลียนแบบพฤติกรรมเชิงโครงสร้างของทริกเกอร์มาตรฐานSQL:2003แต่ได้รับการปรับแต่งให้เหมาะสมกับรูปแบบการสืบค้นและอัปเดต XML โดยเฉพาะ รวมถึงXPath , XQueryและส่วนขยายการอัปเดต XML

ใน Sedna สามารถกำหนดทริกเกอร์ให้กับโหนดใดๆ ภายในเอกสาร XML ที่จัดเก็บอยู่ในฐานข้อมูลได้ เมื่อโหนดเป้าหมายเหล่านี้ได้รับการแก้ไข ทริกเกอร์จะเรียกใช้คำสั่ง XQuery หรือสคริปต์การอัปเดตที่เกี่ยวข้องโดยอัตโนมัติ ซึ่งกำหนดไว้ในส่วนเนื้อหาของทริกเกอร์ ตัวอย่างเช่น ทริกเกอร์ต่อไปนี้จะบล็อกการลบโหนดpersonหากยังมีรายการประมูลที่เปิดอยู่ซึ่งอ้างอิงถึงโปรไฟล์นั้นๆ:

สร้างทริกเกอร์"trigger3" ก่อนลบในdoc( "auction" )/ site // person สำหรับแต่ละโหนดทำซ้ำ{ ถ้ามีอยู่( $ WHERE // open_auction / bidder / personref / @person = $ OLD / @id )) แล้ว( ) มิฉะนั้น$ OLD ; }

ทริกเกอร์ฐานข้อมูล MongoDB

ในMongoDB Atlas ทริกเกอร์ถูกนำมาใช้เป็นส่วนหนึ่งของสถาปัตยกรรมแบบไร้เซิร์ฟเวอร์และขับเคลื่อนด้วยเหตุการณ์ เพื่อดำเนินการตรรกะฝั่งเซิร์ฟเวอร์อัตโนมัติเมื่อมีการเปลี่ยนแปลงข้อมูล แตกต่างจากทริกเกอร์ฐานข้อมูลแบบดั้งเดิมซึ่งทำงานโดยตรงบนเซิร์ฟเวอร์ฐานข้อมูล ทริกเกอร์ฐานข้อมูลของ MongoDB Atlas ทำงานบนเลเยอร์การประมวลผลที่ปรับขนาดได้อย่างอิสระ โดยจะตรวจสอบการแก้ไขข้อมูลแบบเรียลไทม์ ( INSERT, UPDATE, REPLACE, หรือDELETE) โดยใช้Change Streams[ 14 ] เมื่อตรวจพบเหตุการณ์ ทริกเกอร์จะเรียกใช้ฟังก์ชัน Atlas แบบกำหนดเอง (เขียนด้วย JavaScript) โดยอัตโนมัติ หรือส่งเหตุการณ์ไปยังบริการภายนอก ฟังก์ชันนี้ใช้เป็นหลักในการบังคับใช้ความสอดคล้องของข้อมูลและความสมบูรณ์ของข้อมูล และเพื่อดำเนินการตรวจสอบโดยอัตโนมัติทั่วทั้งระบบนิเวศข้อมูล

ร้านค้าออนไลน์ที่ติดตามการจัดส่งพัสดุอาจใช้ทริกเกอร์ในฐานข้อมูลเพื่อแจ้งเตือนลูกค้าเมื่อใดก็ตามที่พัสดุของพวกเขาเปลี่ยนสถานที่ ทริกเกอร์จะตรวจสอบการเปลี่ยนแปลงข้อมูลภายในstore.ordersชุดข้อมูล ซึ่งคำสั่งซื้อที่ใช้งานอยู่แต่ละรายการจะถูกจัดเก็บเป็นเอกสารที่มีโครงสร้างดังตัวอย่างต่อไปนี้:

{ _id : Object Id( " 59cf1860a95168b8f685e378" ) , customerId : Object Id ( "59cf17e1a95168b8f685e377" ) , orderDate : ISODate ( " 2018-06-26T16 :20:42.313Z" ) , shipDate : ISODate ( "2018-06-27T08:20:23.311Z" ) , orderContents : [ { qty : 1 , name : " Earl Grey Tea Bags - 100ct " , price : NumberDecimal ( " 10.99 " ) } ] , shippingLocatio } n : [ { location : " Memphis " , time : ISODate ( " 2018-06-27T18 : 22:33.243Z" ) }, ] }

สถาปัตยกรรมและการก่อสร้าง

ระดับความละเอียดและจังหวะเวลาในการดำเนินการ

เพื่อให้เข้าใจวิธีการทำงานของทริกเกอร์ในฐานข้อมูล จำเป็นต้องพิจารณาสองแนวคิดหลัก ได้แก่ระดับความละเอียด ของทริกเกอร์ (ระดับแถวเทียบกับระดับคำสั่ง) และเวลาในการดำเนินการ (ก่อนเทียบกับหลัง) การตั้งค่าเหล่านี้จะกำหนดว่าทริกเกอร์จะทำงานกี่ครั้งและโค้ดของทริกเกอร์จะทำงานเมื่อใด

ระดับแถวเทียบกับระดับคำสั่ง

ความแตกต่างหลักระหว่างทริกเกอร์ทั้งสองประเภทนี้อยู่ที่ความถี่ในการทำงานเมื่อมีการเปลี่ยนแปลงข้อมูล:

  • ทริกเกอร์ระดับแถวจะทำงานหนึ่งครั้งสำหรับทุกแถวที่ได้รับผลกระทบจากคำสั่งฐานข้อมูล เช่น คำสั่งINSERT`print` UPDATE, `print` หรือDELETE`print` ตัวอย่างเช่น หากUPDATEคำสั่งเปลี่ยนแปลง 50 แถวในตาราง ทริกเกอร์ระดับแถวจะทำงาน 50 ครั้ง หากคำสั่งไม่ตรงกับแถวใด ๆ และไม่เปลี่ยนแปลงอะไรเลย ทริกเกอร์ระดับแถวจะไม่ทำงานเลย
  • ทริกเกอร์ระดับคำสั่งจะทำงานเพียงครั้งเดียวสำหรับคำสั่ง SQL ทั้งหมด โดยไม่คำนึงถึงจำนวนแถวที่เปลี่ยนแปลง แม้ว่าคำสั่งฐานข้อมูลจะไม่มีผลกระทบต่อแถวใด ๆ เลยก็ตาม ทริกเกอร์ระดับคำสั่งก็จะยังคงเรียกใช้โค้ดของมันหนึ่งครั้ง

ระดับความละเอียดของการเรียกใช้ทริกเกอร์จะแตกต่างกันไปตามเอนจิ้น โดยระบบอย่าง PostgreSQL ใช้FOR EACH ROWทริกเกอร์ระดับแถว ในขณะที่ Microsoft SQL Server ใช้ทริกเกอร์ระดับคำสั่งเป็นค่าเริ่มต้น และต้องจัดการแถวผ่านตารางเสมือน นักพัฒนาต้องหลีกเลี่ยงการเรียก ใช้ทริกเกอร์ ซ้ำซ้อน ซึ่งทริกเกอร์จะอัปเดตตารางแล้วเรียกใช้ตัวเองอีก ทำให้เกิดลูปไม่สิ้นสุดและอาจทำให้ฐานข้อมูลล่มได้

ก่อนและหลัง

ตัวเลือกด้านเวลา ซึ่งระบุโดยใช้ คำหลัก BEFOREและAFTERจะกำหนดว่าทริกเกอร์จะทำงานเมื่อใดเมื่อเทียบกับการแก้ไขข้อมูล:

  • BEFOREทริกเกอร์จะทำงานก่อนที่การเปลี่ยนแปลงข้อมูลจะถูกบันทึกอย่างถาวรลงในตาราง การใช้งานทBEFOREริกเกอร์ที่พบบ่อยคือการตรวจสอบความถูกต้องของข้อมูลขาเข้าหรือการตรวจสอบความปลอดภัย ตัวอย่างเช่นBEFOREทริกเกอร์สามารถตรวจสอบระเบียนที่เข้ามาและแก้ไขค่าที่ไม่ถูกต้องหรือหยุดการทำงานทั้งหมดก่อนที่จะเขียนข้อมูลใดๆ ลงดิสก์
  • AFTERทริกเกอร์จะเรียกใช้โค้ดหลังจากที่การเปลี่ยนแปลงข้อมูลได้รับการเขียนลงในตารางอย่างปลอดภัยแล้ว โดยทั่วไปทริกเกอร์เหล่านี้จะใช้สำหรับงานประมวลผลภายหลัง เช่น การบันทึกข้อมูลประวัติหรือการสร้างบันทึกการตรวจสอบ ในขณะที่BEFOREทริกเกอร์เหมาะที่สุดสำหรับการตรวจสอบและทำความสะอาดข้อมูลที่เข้ามาAFTERทริกเกอร์เหมาะอย่างยิ่งสำหรับการคัดลอกการเปลี่ยนแปลงที่ได้รับการยืนยันไปยังตารางประวัติหรือตารางบันทึกแยกต่างหาก[ 15 ]

ตัวอย่างการใช้งาน (Oracle PL/SQL)

ตัวอย่างต่อไปนี้แสดงทริกเกอร์ระดับแถวของ Oracle PL/SQL ที่กำหนดค่าให้ทำงานหลังจากUPDATEดำเนินการกับตารางชื่อ `<table>` phone_bookทริกเกอร์นี้จะบันทึกการเปลี่ยนแปลงในอดีตโดยอัตโนมัติโดยการเขียนรายการบันทึกไปยังตารางติดตามแยกต่างหากชื่อ `<table>` phone_book_auditนอกจากนี้ยังใช้ลำดับฐานข้อมูลชื่อ `<table>` audit_id_sequenceเพื่อสร้างหมายเลข ID ที่ไม่ซ้ำกันสำหรับรายการบันทึกใหม่แต่ละรายการ:

สร้างหรือแทนที่ทริกเกอร์phone_book_audit หลังจากอัปเดตในตาราง phone_book สำหรับแต่ละแถวเริ่มต้นแทรกข้อมูลลงในphone_book_audit ( audit_id , audit_change , audit_l_name , audit_f_name , audit_old_phone_number , audit_new_phone_number , audit_date ) ด้วยค่า( audit_id_sequence . nextVal , 'Update' , : OLD . last_name , : OLD . first_name , : OLD . phone_number , : NEW . phone_number , SYSDATE ); สิ้นสุด;

คำUPDATEสั่งที่ดำเนินการกับphone_bookตารางจะแก้ไขระเบียนที่มีนามสกุล "Jones":

อัปเดต สมุด โทรศัพท์ตั้งค่าหมายเลขโทรศัพท์เป็น'111-111-1111' โดยที่นามสกุลเท่ากับ'Jones' ;
รหัสตรวจสอบการตรวจสอบการเปลี่ยนแปลงชื่อการตรวจสอบ L_ชื่อการตรวจสอบ Fตรวจสอบหมายเลขโทรศัพท์เก่าตรวจสอบหมายเลขโทรศัพท์ใหม่วันที่ตรวจสอบ
1อัปเดตโจนส์จอร์แดน098-765-4321111-111-111102-พฤษภาคม-14
2อัปเดตโจนส์เมแกน111-222-3456111-111-111102-พฤษภาคม-14

ตาราง ผลลัพธ์phone_book_auditจะมีรายการที่แตกต่างกันสองรายการ เนื่องจากฐานข้อมูลต้นทางมีระเบียนสองรายการที่ตรงกับนามสกุล "Jones" เนื่องจากทริกเกอร์ระดับแถวจะทำงานหนึ่งครั้งสำหรับแต่ละแถวที่แก้ไข เอ็นจิ้นจึงเรียกใช้ตรรกะทริกเกอร์สองครั้งในระหว่างการดำเนินการคำสั่งอัปเดตเดียว[ 16 ]

หลังจากทริกเกอร์ระดับคำสั่ง

ในทางกลับกันAFTERทริกเกอร์ระดับคำสั่งจะทำงานเพียงครั้งเดียวต่อการดำเนินการคำสั่งเสร็จสิ้นแต่ละครั้ง โดยไม่คำนึงถึงจำนวนแถวทั้งหมดที่ถูกแก้ไขโดยคำสั่งนั้น ไวยากรณ์ของ Oracle ต่อไปนี้กำหนดทริกเกอร์ระดับคำสั่งที่บันทึกเหตุการณ์ธุรกรรมเดียวภายในphone_book_edit_historyตารางทุกครั้งที่UPDATEมีการดำเนินการเกิดขึ้นกับphone_bookตาราง:

สร้างหรือแทนที่ทริกเกอร์phone_book_history หลังจากอัปเดตในphone_book โดยเริ่ม ต้น ด้วยการแทรกข้อมูลลงในphone_book_edit_history ( audit_history_id , username , modification , edit_date ) ด้วยค่า( audit_history_id_sequence . nextVal , USER , 'Update' , SYSDATE ); สิ้นสุด;

การดำเนินการตามคำสั่งเดียวกันUPDATEจะแยกความแตกต่างด้านพฤติกรรมของตัวกระตุ้นระดับคำสั่ง:

อัปเดต สมุด โทรศัพท์ตั้งค่าหมายเลขโทรศัพท์เป็น'111-111-1111' โดยที่นามสกุลเท่ากับ'Jones' ;
รหัสประวัติการตรวจสอบชื่อผู้ใช้การแก้ไขวันที่แก้ไข
1บอนยอร์อัปเดต02-พฤษภาคม-14

บันทึกธุรกรรมระบุว่าทริกเกอร์ทำงานเพียงครั้งเดียวเท่านั้น แม้ว่าการแก้ไขข้อมูลจะส่งผลกระทบต่อข้อมูลสองรายการแยกกันก็ตาม

ก่อนทริกเกอร์ระดับแถวพร้อมการกรองแบบมีเงื่อนไข

BEFOREริกเกอร์ระดับแถวจะประเมินและเปลี่ยนแปลงค่าข้อมูลที่เข้ามา ก่อนที่การดำเนินการเขียนทางกายภาพจะเสร็จสมบูรณ์บนดิสก์ รูปแบบนี้แสดงให้เห็นถึงทริกเกอร์ที่ใช้WHENข้อจำกัดของข้อความเพื่อดักจับINSERTการกระทำ เมื่อเรคอร์ดมีสตริงนามสกุลที่มีความยาวเกิน 10 ตัวอักษร เอ็นจิ้นจะเรียกใช้SUBSTRฟังก์ชัน[ 17 ]เพื่อตัดค่าอินพุตให้เหลือเพียงอักขระตัวแรก: [ 18 ]

สร้างหรือแทนที่ริกเกอร์phone_book_insert ก่อนแทรกข้อมูลลงในตารางphone_book สำหรับแต่ละแถวเมื่อความยาวของนามสกุลใหม่มากกว่า10 ให้เริ่มต้นที่: นามสกุลใหม่: = ลบนามสกุลใหม่ด้วยค่า0 และ1

กลไกนี้จะสังเกตได้เมื่อพยายามแทรกข้อมูลที่ตรงตามเกณฑ์การกรอง:

INSERT INTO phone_book VALUES ( 6 , 'VeryVeryLongLastName' , 'Erin' , 'Minneapolis' , 'MN' , '989 University Drive' , '123-222-4456' , 55408 , TO_DATE ( '11/21/1991' , 'MM/DD/YYYY' ));
รหัสบุคคลนามสกุลชื่อจริงเมืองตัวย่อของรัฐที่อยู่หมายเลขโทรศัพท์รหัสไปรษณีย์วันเกิด
6วีเอรินมินนิอาโพลิสMN989 ถนนยูนิเวอร์ซิตี้ไดรฟ์123-222-44565540821 พ.ย. 91

เอนจินจะยืนยันข้อมูลแถวที่มีตัวแปรนามสกุลที่ถูกตัดทอน เพื่อยืนยันว่าการแก้ไขเกิดขึ้นก่อนที่จะเขียนระเบียนลงในตาราง

ก่อนที่จะเกิดทริกเกอร์ระดับคำสั่งและการยกเว้น

การใช้งานBEFOREทริกเกอร์ระดับคำสั่งเป็นรูปแบบการออกแบบมาตรฐานสำหรับการบังคับใช้พารามิเตอร์ความปลอดภัยหรือข้อจำกัดกฎทางธุรกิจทั่วโลกในทรัพยากรฐานข้อมูล[ 19 ]คำจำกัดความต่อไปนี้จำกัดการเข้าถึงฐานข้อมูลบนตารางเป้าหมายภายใต้สคีมาเฉพาะ:

CREATE OR REPLACE TRIGGER hauschbc BEFORE INSERT ON SOMEUSER . phone_book BEGIN RAISE_APPLICATION_ERROR ( num => - 20050 , msg => 'ข้อความแสดงข้อผิดพลาดอยู่ที่นี่' ); END ;

การพยายามแทรกข้อมูลไปยังทรัพยากรที่ได้รับการป้องกันจะทำให้เอนจินฐานข้อมูลยกเลิกกระบวนการและส่งข้อความแสดงข้อผิดพลาดกลับไปยังอินเทอร์เฟซแอปพลิเคชันไคลเอ็นต์ที่เรียกใช้งาน:

ข้อผิดพลาด SQL: ORA-20050: ข้อความแสดงข้อผิดพลาดอยู่ที่นี่

ข้อยกเว้นรันไทม์ที่กำหนดเองซึ่งเกิดขึ้นผ่านRAISE_APPLICATION_ERRORโปรโตคอลนั้นอยู่ภายใต้ช่วงตัวเลขที่จำกัด เพื่อหลีกเลี่ยงความขัดแย้งกับรหัสข้อผิดพลาดของระบบที่กำหนดไว้ล่วงหน้า นักพัฒนาแอปพลิเคชันต้องกำหนดตัวแปรนี้ภายในขอบเขตตัวเลขระหว่าง -20000 ถึง -20999

  • Microsoft SQL Server DROP TRIGGER
  • ทริกเกอร์ฐานข้อมูล MySQL
  • สร้างทริกเกอร์ในฐานข้อมูล MySQL
  • คำสั่ง DB2 CREATE TRIGGER
  • Oracle สร้างทริกเกอร์
  • PostgreSQL สร้างทริกเกอร์
  • ปัญหาการแก้ไขตารางใน Oracle เมื่อใช้คำสั่ง DELETE CASCADE
  • ภาษาการสืบค้น SQLite: สร้างทริกเกอร์
  • เอกสารของ Oracle เกี่ยวกับทริกเกอร์

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ไม่มีชื่อบทความ

ท ริกเกอร์ฐานข้อมูล คือ โค้ดขั้นตอน ที่ดำเนินการโดยอัตโนมัติเพื่อตอบสนองต่อ เหตุการณ์ เฉพาะ บน ตาราง หรือ มุมมอง ใน ฐานข้อมูล ทริกเกอร์มักใช้เพื่อรักษา ความสมบูรณ์ ของข้อมูล...

ทริกเกอร์ในระบบจัดการฐานข้อมูล (DBMS)

ด้านล่างนี้คือภาพรวมของวิธีการที่ ระบบจัดการ ฐานข้อมูล (DBMS) ทั่วไปหลายระบบ รองรับทริกเกอร์

ออราเคิล

นอกเหนือจาก ทริกเกอร์ ภาษาการจัดการข้อมูลมาตรฐาน (DML) ที่เรียกใช้ โค้ด PL/SQL เมื่อมีการแก้ไขข้อมูลแล้ว Oracle ยังรองรับทริกเกอร์ที่ทำงานเมื่อมีการเปลี่ยนแปลงระดับสคีมาและเหตุการณ์ฐานข้อมูลทั่วทั้งระบบ ทั้งทริกเกอร์ภาษาการกำหนดข้อมูลระดับสคีมา (DDL)...

ไมโครซอฟต์ SQL Server

Microsoft SQL Server รองรับทริกเกอร์สำหรับคำสั่ง DML และ DDL รวมถึงทริกเกอร์พิเศษ "การเข้าสู่ระบบ" ด้วย