ทริกเกอร์เพื่อเพิ่ม การสร้างและการใช้ทริกเกอร์ ไวยากรณ์คำจำกัดความฟังก์ชันทริกเกอร์

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

วัตถุประสงค์ของทริกเกอร์

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

ประกาศทริกเกอร์

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

[จบ]

คำหลัก

. ก่อน|หลัง– เวลาเริ่มต้นของทริกเกอร์ – ก่อน | หลังจากการดำเนินการอัพเดต
. ลบ|แทรก|อัปเดต= เหตุการณ์ทริกเกอร์
. สำหรับแต่ละแถว– สำหรับแต่ละบรรทัด (ทริกเกอร์บรรทัด จากนั้นเมื่อ)
. สำหรับแต่ละแถลงการณ์– สำหรับทั้งทีม (ถูกต้องตามค่าเริ่มต้น)
. อ้างอิง– อนุญาตให้คุณกำหนดนามแฝงได้สูงสุด 4 ชื่อให้กับ old และ | หรือบรรทัดใหม่และ | หรือตารางที่สามารถเข้าถึงได้โดยทริกเกอร์

ข้อจำกัดของทริกเกอร์

เนื้อความของทริกเกอร์ต้องไม่มีข้อความต่อไปนี้:
- การกำหนด การลบ และการเปลี่ยนแปลงวัตถุฐานข้อมูล (ตาราง โดเมน ฯลฯ)
- การประมวลผลธุรกรรม (COMMIT, ROLLBACK)
- การเชื่อมต่อและการตัดการเชื่อมต่อไปยังฐานข้อมูล (CONNECT, DISCONNECT)

คุณสมบัติของแอพพลิเคชั่น
- ทริกเกอร์จะดำเนินการหลังจากใช้การตรวจสอบความสมบูรณ์อื่นๆ (ที่ประกาศ) ทั้งหมดแล้ว และมีประโยชน์เมื่อเกณฑ์การทดสอบค่อนข้างซับซ้อน หากการตรวจสอบที่เปิดเผยปฏิเสธการดำเนินการอัพเดต ทริกเกอร์จะไม่ถูกดำเนินการ ทริกเกอร์ทำงานในบริบทของธุรกรรม แต่ข้อจำกัด FK จะไม่ทำงาน
- หากทริกเกอร์ทำให้เกิดการเปลี่ยนแปลงเพิ่มเติมในตารางฐาน บ่อยครั้งสิ่งนี้จะไม่นำไปสู่การดำเนินการแบบเรียกซ้ำ แต่ควรชี้แจงให้ชัดเจน ในดีบีเอ็มเอส เซิร์ฟเวอร์ SQL 2005 จัดเตรียมความสามารถในการระบุการเรียกซ้ำได้มากถึง 255 ระดับโดยใช้คีย์เวิร์ด OPTION (MAXRECURSIV 3)
- โดยทั่วไปทริกเกอร์จะไม่ถูกดำเนินการเมื่อประมวลผลคอลัมน์ไบนารีขนาดใหญ่ (BLOB)
- ควรจำไว้ว่าเมื่อใดก็ตามที่ข้อมูลได้รับการอัปเดต DBMS จะสร้างสิ่งที่เรียกว่าตารางเสมือนทริกเกอร์โดยอัตโนมัติ ซึ่งใน DBMS ต่างๆ นั้น ชื่อที่แตกต่างกัน- ใน InterBase และ Oracle - สิ่งเหล่านี้ใหม่และเก่า ใน SQL Server - แทรกและลบแล้ว ยิ่งไปกว่านั้น เมื่อข้อมูลเปลี่ยนแปลง ทั้งสองก็จะถูกสร้างขึ้น ตารางเหล่านี้มีจำนวนคอลัมน์เท่ากัน โดยมีชื่อและโดเมนเดียวกันกับตารางที่กำลังอัปเดต SQL Server 2005 DBMS ให้ความสามารถในการระบุตาราง รวมถึงตารางชั่วคราว ที่ควรแทรกข้อมูลลงในโดยใช้คีย์เวิร์ด OUTPUT Inserted.ID,... INTO @
- ใน DBMS จำนวนหนึ่ง อนุญาตให้ประกาศทริกเกอร์สำหรับการดำเนินการหลายอย่างพร้อมกันได้ เพื่อนำปฏิกิริยาต่าง ๆ ไปปฏิบัติ การกระทำต่างๆ Oracle จัดเตรียมเพรดิเคตการลบ การแทรก การอัพเดตที่ส่งคืน True สำหรับประเภทการอัพเดตที่เกี่ยวข้อง
- ใน ออราเคิล DBMSคุณสามารถระบุรายการคอลัมน์สำหรับทริกเกอร์การอัปเดต (หลังการอัปเดต) ซึ่งจะทำให้แน่ใจได้ว่าทริกเกอร์จะถูกเรียกเฉพาะเมื่อค่าของคอลัมน์เหล่านี้เท่านั้นที่เปลี่ยนแปลง
- สามารถประกาศทริกเกอร์ได้หลายตัวสำหรับแต่ละเหตุการณ์ทริกเกอร์ (Oracle มี 12 ทริกเกอร์ต่อตาราง) และโดยปกติแล้วลำดับที่ทริกเกอร์จะเริ่มทำงานจะขึ้นอยู่กับลำดับที่สร้างขึ้น ใน DBMS บางตัว เช่น InterBase ลำดับการเริ่มต้นระบบจะถูกระบุโดยใช้คีย์เวิร์ดเพิ่มเติม POSITION โดยทั่วไป ควรดำเนินการทริกเกอร์สำหรับแต่ละคำสั่งก่อน จากนั้นจึงสำหรับแต่ละบรรทัด
- ทริกเกอร์สามารถฝังอยู่ภายในกันและกันได้ ดังนั้น SQL Server อนุญาตให้มีระดับการซ้อน 32 ระดับ (คุณสามารถใช้ตัวแปรส่วนกลาง @@NextLevel เพื่อกำหนดระดับการซ้อนได้)

ข้อเสียของทริกเกอร์

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

การแก้ไขและการลบทริกเกอร์

หากต้องการลบทริกเกอร์ ให้ใช้คำสั่ง DROP TRIGGER
- หากต้องการเปลี่ยนทริกเกอร์ ให้ใช้คำสั่ง ALTER TRIGGER...
- ปิดการใช้งานทริกเกอร์
ในบางกรณี เช่น ระหว่างการโหลดเป็นชุด จำเป็นต้องปิดใช้งานทริกเกอร์ DBMS จำนวนหนึ่งมีความสามารถที่สอดคล้องกัน ในออราเคิลและ SQL รหัสเซิร์ฟเวอร์คำว่า DISABLE|ENABLE ใน InterBase INACTIVE|ACTIVE ใน คำสั่งเปลี่ยนแปลงสิ่งกระตุ้น.

คุณสมบัติของเซิร์ฟเวอร์อุตสาหกรรม

1) อินเตอร์เบส/ไฟร์เบิร์ด

สร้างทริกเกอร์ สำหรับ {ใช้งานอยู่ | ไม่ใช้งาน} {ก่อน|หลัง} {แทรก|ลบ|อัปเดต} [ตำแหน่ง ]
เช่น [ประกาศตัวแปร [()]]
เริ่ม

จบ

ตัวอย่าง:

สร้างทริกเกอร์ BF_Del_Cust สำหรับลูกค้า
ใช้งานก่อนที่จะลบตำแหน่ง 1 AS
เริ่ม
ลบออกจากคำสั่งซื้อโดยที่ Order.CNum=Customer.CNum;
จบ;

2) เซิร์ฟเวอร์ SQL

สร้างทริกเกอร์ บน [ด้วยการเข้ารหัส] {สำหรับ|หลัง|แทน} {แทรก|อัปเดต|ลบ}
เช่น

ใช้ B1;
ไป
สร้างทริกเกอร์ InUpCust1 บนลูกค้าหลังจากแทรก อัปเดต
AS RISEERROR('ตารางลูกค้ามีการเปลี่ยนแปลง');

ทริกเกอร์ประเภทเพิ่มเติม

Oracle และ SQL Server มอบความสามารถในการสร้าง (แทนที่) ทริกเกอร์สำหรับมุมมองที่ไม่ได้รับการอัพเดต สำหรับสิ่งนี้ จะมีการจัดเตรียมคำหลัก INSTEAD OF:

สร้างทริกเกอร์แทนการแทรกเป็น ...

คุณสามารถตรวจสอบความพยายามของลูกค้าในการอัปเดตข้อมูลโดยใช้มุมมองและดำเนินการใดๆ จัดการมุมมองที่ไม่ได้รับการอัปเดต ฯลฯ
- SQL Server DBMS มีทริกเกอร์การย้อนกลับที่หยุดการกระทำทั้งหมดและแสดงข้อความ:

ทริกเกอร์ย้อนกลับ

สิ่งกระตุ้น (สิ่งกระตุ้น) เป็นขั้นตอนการจัดเก็บชนิดพิเศษที่ผู้ใช้ไม่ได้เรียกใช้โดยตรง และการดำเนินการนั้นมีเงื่อนไขตามการเกิดเหตุการณ์บางอย่าง (การกระทำ) โดยพื้นฐานแล้วจะเป็นการเพิ่ม INSERT หรือการลบแถว DELETE ในตารางที่กำหนด หรือการแก้ไข อัปเดตข้อมูลในคอลัมน์เฉพาะของตารางที่กำหนด ฐานสัมพันธ์ข้อมูล. ทริกเกอร์ใช้เพื่อรับรองความสมบูรณ์ของข้อมูลและใช้ตรรกะทางธุรกิจที่ซับซ้อน ทริกเกอร์จะเริ่มทำงานโดยอัตโนมัติโดยเซิร์ฟเวอร์เมื่อมีการพยายามเปลี่ยนแปลงข้อมูลในตารางที่เชื่อมโยงอยู่ การปรับเปลี่ยนข้อมูลทั้งหมดที่ทำขึ้นจะถือว่าดำเนินการในธุรกรรมซึ่งมีการดำเนินการที่ทำให้เกิดการทริกเกอร์ ดังนั้นหากตรวจพบข้อผิดพลาดหรือการละเมิด ความสมบูรณ์ของข้อมูลธุรกรรมนี้อาจถูกย้อนกลับ

ทริกเกอร์ถูกสร้างขึ้นแยกกันสำหรับแต่ละตารางและอยู่ใน Object Explorer ในโฟลเดอร์ "ทริกเกอร์" มาสร้างทริกเกอร์สำหรับตาราง "ครู" กันเถอะ โฟลเดอร์ "Triggers" จะเป็นส่วนหนึ่งของตาราง "ครู":

มาสร้างทริกเกอร์ที่แสดงข้อความ “บันทึกเพิ่ม” เมื่อมีการเพิ่มบันทึกลงในตาราง มาสร้างทริกเกอร์ใหม่โดยคลิกขวาที่โฟลเดอร์ "ทริกเกอร์" ในตาราง "ครู" และเลือก "ทริกเกอร์ใหม่" จากเมนูที่ปรากฏขึ้น หน้าต่างต่อไปนี้พร้อมกับทริกเกอร์ใหม่จะปรากฏขึ้น:

ลองดูที่โครงสร้างของทริกเกอร์:

1) ขอบเขตของชื่อฟังก์ชัน (Trigger_Name)

2) พื้นที่ที่แสดงตารางที่กำลังสร้างทริกเกอร์ (Table_Name)

3) พื้นที่ที่แสดงเวลาที่จะดำเนินการทริกเกอร์ (INSERT - เมื่อสร้างบันทึกในตาราง DELETE - เมื่อลบและ UPDATE - เมื่อเปลี่ยนแปลง) และวิธีการดำเนินการ (ALTER - หลังจากดำเนินการดำเนินการ แทน - แทนที่จะดำเนินการ การดำเนินการ);

4) เนื้อความของทริกเกอร์ประกอบด้วยคำสั่งของภาษาการเขียนโปรแกรมแบบสอบถาม TSQL

ในหน้าต่างทริกเกอร์ใหม่ ให้ป้อนรหัส:

สร้างทริกเกอร์ tr_add

บน dbo.teachers

พิมพ์ "เพิ่มรายการใหม่"

จากรูป คุณจะเห็นว่าทริกเกอร์ “Add Indicator” ที่สร้างขึ้นถูกดำเนินการหลังจากเพิ่มบันทึก (หลังจากแทรก) ลงในตาราง “dbo.teachers” (ON dbo.teachers) หลังจากเพิ่มรายการแล้ว ทริกเกอร์จะแสดงข้อความ "เพิ่มรายการใหม่แล้ว" (พิมพ์ "เพิ่มรายการใหม่แล้ว") มารันโค้ดที่พิมพ์โดยคลิกที่ปุ่มบนแถบเครื่องมือ ข้อความ “คำสั่งเสร็จสมบูรณ์” จะปรากฏที่ด้านล่างของหน้าต่างโค้ด

มาดูกันว่าทริกเกอร์ใหม่ทำงานอย่างไร มาสร้างคำขอว่างใหม่และป้อนคำสั่งต่อไปนี้เพื่อเพิ่ม รายการใหม่ไปที่ตาราง “dbo.teachers”:

แทรกลงใน dbo.teachers

"ซิโดรอฟ"

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

ทริกเกอร์ที่มี UPDATE และ DELETE ถูกสร้างขึ้นในลักษณะเดียวกัน

การมอบหมาย: ตามด้วยธีมของคุณเอง สร้างในSQLเซิร์ฟเวอร์การจัดการสตูดิโอการแสดง (3-4)แบบสอบถาม (3-4), ขั้นตอนการจัดเก็บ (3-4), ฟังก์ชั่นที่ผู้ใช้กำหนด (3-4), ทริกเกอร์ (INSERT,อัปเดตและลบ- ใช้คำสั่งแบบมีเงื่อนไขและลูปเมื่อสร้างตัวดำเนินการ

ทริกเกอร์ sql เป็นขั้นตอนการจัดเก็บชนิดพิเศษที่เซิร์ฟเวอร์ดำเนินการโดยอัตโนมัติเมื่อข้อมูล (DML) ในตารางเชื่อมโยงกับการเปลี่ยนแปลง ทริกเกอร์เชื่อมต่อกับตารางเฉพาะ การเปลี่ยนแปลงข้อมูลทั้งหมดที่กระทำโดยทริกเกอร์จะถือเป็นธุรกรรมเดียว

ต่างจากขั้นตอน/ฟังก์ชันที่เก็บไว้ทั่วไป ทริกเกอร์จะถูกเรียกโดยเซิร์ฟเวอร์โดยปริยายเมื่อมีเหตุการณ์ทริกเกอร์เฉพาะเกิดขึ้น นอกจากนี้ ทริกเกอร์ SQL ไม่มีอาร์กิวเมนต์ งานต่อไปนี้ได้รับการแก้ไขโดยใช้ทริกเกอร์:

  • การตรวจสอบความถูกต้องของข้อมูลที่มีการเปลี่ยนแปลง และตรวจสอบข้อจำกัดด้านความสมบูรณ์ของข้อมูลที่ซับซ้อนซึ่งจำเป็นต้องได้รับการดูแล
  • การสะสม ข้อมูลทางสถิติโดยการบันทึกข้อมูลเกี่ยวกับการเปลี่ยนแปลงที่เกิดขึ้น
  • การสนับสนุนการจำลองแบบ

การใช้ข้อจำกัดด้านความสมบูรณ์ กฎเกณฑ์ที่ตั้งขึ้นและค่าต่างๆ ไม่สามารถบรรลุระดับความสมบูรณ์ของข้อมูลที่ต้องการได้เสมอไป บางครั้งคุณจำเป็นต้องดำเนินการ อัลกอริธึมที่ซับซ้อนการตรวจสอบข้อมูลเพื่อให้มั่นใจถึงความน่าเชื่อถือและความเป็นจริง นอกจากนี้มักจำเป็นต้องติดตามการเปลี่ยนแปลงค่าตารางเพื่อที่จะ ในทางที่ถูกต้องเปลี่ยนแปลงข้อมูลที่เกี่ยวข้อง ทริกเกอร์ SQLถือได้ว่าเป็นตัวกรองประเภทหนึ่งที่มีผลใช้บังคับหลังจากการดำเนินการทั้งหมดเสร็จสิ้นตามกฎแล้ว ค่ามาตรฐานฯลฯ

แอปพลิเคชัน ทริกเกอร์ SQL เกี่ยวข้องกับต้นทุนทรัพยากรเซิร์ฟเวอร์เพิ่มเติมสำหรับการเพิ่มการดำเนินการ ( ทริกเกอร์แทรก) การอัปเดต ( อัปเดตทริกเกอร์) หรือการลบ ( ทริกเกอร์ลบ) ข้อมูลในตาราง

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

สร้างทริกเกอร์

รูปแบบพื้นฐานของคำสั่ง CREATE TRIGGER แสดงอยู่ด้านล่าง:

สร้างทริกเกอร์ trigger_name [ ก่อน | หลังจาก ] เปิด table_name เริ่มต้น จบ;

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

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

สามารถเรียกทริกเกอร์ได้สำหรับแต่ละบรรทัด ( สำหรับแต่ละแถว) ครอบคลุมตามเหตุการณ์ที่กำหนด หรือเพียงครั้งเดียวสำหรับแต่ละเหตุการณ์ ( สำหรับแต่ละแถลงการณ์).

การกำหนด<список_псевдонимов>หมายถึงส่วนประกอบต่างๆ เช่น แถวเก่าหรือใหม่ (OLD / NEW) หรือตารางเก่าหรือใหม่ (OLD TABLE / NEW TABLE) ค่าเก่าใช้ไม่ได้กับเหตุการณ์การแทรก และค่าใหม่ใช้ไม่ได้กับเหตุการณ์การลบ

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

ทริกเกอร์ที่เขียนไม่ถูกต้องอาจนำไปสู่ ปัญหาร้ายแรงเกี่ยวข้องกับลักษณะของการอุดตัน ทริกเกอร์มีความสามารถ เวลานานบล็อกทรัพยากร ดังนั้นควรให้ความสนใจเป็นพิเศษเพื่อลดความขัดแย้งในการเข้าถึง

ทริกเกอร์ MS SQL

ไวยากรณ์สำหรับการสร้างทริกเกอร์ใน MS SQL DBMS มีดังนี้:

สร้างทริกเกอร์ trigger_name ON (พร้อมการเข้ารหัส) [ [,] [,] ] [ พร้อมผนวก ] [ ไม่ใช่สำหรับการจำลอง ] AS ( sql_statement )

สคีมา_ชื่อ

ชื่อของวงจรทริกเกอร์ DML การกระทำ ทริกเกอร์ DMLจำกัดอยู่ที่ขอบเขตสคีมาของตารางหรือมุมมองที่ถูกสร้างขึ้น ไม่สามารถระบุ schema_name สำหรับทริกเกอร์ DDL หรือทริกเกอร์การเข้าสู่ระบบได้

trigger_name

ชื่อทริกเกอร์ อาร์กิวเมนต์ trigger_name ต้องเป็นไปตามกฎสำหรับตัวระบุ ยกเว้นว่า trigger_name ไม่สามารถขึ้นต้นด้วยอักขระ # หรือ ##

table_name | view_name

ตารางหรือมุมมองที่มีการแนบทริกเกอร์

ตัวอย่างทริกเกอร์ ms sql

หากต้องการใช้ทริกเกอร์ จะมีการสร้างตาราง 2 ตาราง ได้แก่ test_table, test_log ทริกเกอร์จะเชื่อมต่อกับตาราง test_table เมื่ออัปเดตบันทึกในตาราง test_table ทริกเกอร์จะบันทึกผลลัพธ์ของการเปลี่ยนแปลงในตาราง test_log เหล่านั้น. ทริกเกอร์จะถูกเรียกในเหตุการณ์การอัปเดต

ตารางทดสอบ test_table:

สร้างตาราง dbo.test_table (id int ไม่ใช่ null, field1 varchar(255) null, field2 varchar(255) null, ข้อ จำกัด pkTestTableID คีย์หลัก (id));

ตารางการบันทึก Test_log:

สร้างตาราง dbo.test_log (id bigint identity(1,1) ไม่ใช่ null, table_name varchar(50) ไม่ใช่ null, oper varchar(15) ไม่ใช่ null, record_old xml null, record_new xml null, ข้อมูล datetime null, ข้อ จำกัด คีย์หลัก pkTestLogID ( รหัส));

ทริกเกอร์การอัปเดตข้อมูล:

การอัปเดตทริกเกอร์สร้างทริกเกอร์ dbo.trg_test_table_update บน dbo.test_table สำหรับ UPDATE เมื่อเริ่มต้นตั้งค่า nocount บน - ตัวแปรสำหรับการจัดเก็บข้อมูลเก่าและข้อมูลใหม่ประกาศ @record_new xml;

ประกาศ @record_old xml;

-- ตารางที่ถูกลบจะเก็บชุดข้อมูลเก่า/ที่ถูกลบ @record_old = (SELECT * FROM ถูกลบสำหรับ XML RAW, TYPE);

-- ตารางที่แทรกจะเก็บชุดข้อมูลที่เปลี่ยนแปลง (เพิ่งสร้าง) @record_new = (SELECT * FROM แทรกสำหรับ XML RAW, TYPE);

ถ้า (@record_new ไม่ใช่ null) และ (@record_old ไม่ใช่ null) ให้เริ่มต้นการแทรกลงใน dbo.test_log (table_name, oper, record_old, record_new, data) ค่า ("test_table", "update", @record_old, @record_new , GETDATE ()) สิ้นสุด; จบ;

มาเพิ่มแถวสองสามแถวลงในตารางทดสอบ ซึ่งเราจะอัปเดตเพื่อทดสอบทริกเกอร์:

แทรกลงในค่า dbo.test_table (id, field1, field2) (1, "กาแฟ", "เนสกาแฟ"); แทรกลงในค่า dbo.test_table (id, field1, field2) (2, "Tea" , "Greenfield");

เราตรวจสอบการทำงานของทริกเกอร์โดยอัปเดตแถว:

ตรวจสอบตารางการบันทึก test_log ผลลัพธ์ควรมีลักษณะเหมือนที่แสดงในภาพหน้าจอ:

ข้อมูล XML ได้รับการตรวจสอบและแสดงให้เห็นว่าตารางการบันทึกมีทั้งค่าเก่าและใหม่

ทริกเกอร์ PostgreSQL

ไวยากรณ์สำหรับการสร้างทริกเกอร์ สร้างทริกเกอร์ trigger_name [ เหตุการณ์ [ หรือ เหตุการณ์ ]] บน table_name สำหรับแต่ละ ( ROW | STATEMENT ) ดำเนินการขั้นตอน function_name (อาร์กิวเมนต์)อาร์กิวเมนต์ระบุชื่อของทริกเกอร์ที่จะสร้าง หากจำเป็นสามารถระบุชื่อของโครงการได้ (ก่อน | หลัง)คีย์เวิร์ด BEFORE หมายความว่าเช่นนั้น

ทริกเกอร์ก่อน

และจะต้องดำเนินการฟังก์ชันก่อนที่จะดำเนินการเหตุการณ์ที่เกี่ยวข้อง คีย์เวิร์ด AFTER หมายความว่าเช่นนั้น ทริกเกอร์หลังจากนั้นและฟังก์ชันนี้จะถูกเรียกหลังจากการดำเนินการที่ทริกเกอร์เสร็จสิ้น

( กิจกรรม [ หรือ กิจกรรม... ] )

เหตุการณ์ต่อไปนี้ได้รับการสนับสนุนใน PostgreSQL เมื่อแสดงรายการหลายเหตุการณ์ ให้ใช้ตัวคั่น

คำหลัก สำหรับแต่ละหรือ.

ชื่อของตารางที่การแก้ไขทำให้ทริกเกอร์เริ่มทำงาน

ชื่อของฟังก์ชันที่เรียกว่าพร้อมอาร์กิวเมนต์ ในทางปฏิบัติ อาร์กิวเมนต์จะไม่ถูกใช้เมื่อเรียกใช้ฟังก์ชันทริกเกอร์

ไวยากรณ์คำจำกัดความฟังก์ชันทริกเกอร์

สร้างฟังก์ชัน function_name () ส่งคืนทริกเกอร์ AS DECLARE -- การประกาศตัวแปร BEGIN -- ฟังก์ชันทริกเกอร์ END; ภาษา plpgsql;

ฟังก์ชันทริกเกอร์ใช้ตัวแปรพิเศษที่มีข้อมูลเกี่ยวกับทริกเกอร์ที่เริ่มทำงาน เมื่อใช้ตัวแปรเหล่านี้ ฟังก์ชันทริกเกอร์จะทำงานกับข้อมูล รายการด้านล่างคือตัวแปรบางส่วนที่มีอยู่ในฟังก์ชันทริกเกอร์

ชื่อพิมพ์คำอธิบาย
ใหม่บันทึกค่าฟิลด์ใหม่ของบันทึกที่สร้างโดยคำสั่ง INSERT หรือคำสั่ง UPDATE ที่อัปเดตเมื่อทริกเกอร์ระดับบันทึก (ROW) เริ่มทำงาน ตัวแปรใช้เพื่อแก้ไขบันทึกใหม่ ตัวแปร NEW ใช้ได้เฉพาะระหว่าง INSERT และ UPDATE เท่านั้น ฟิลด์ของระเบียนใหม่สามารถเปลี่ยนแปลงได้โดยทริกเกอร์
เก่าบันทึกค่าฟิลด์บันทึกเก่าที่มีอยู่ในบันทึกก่อนที่คำสั่ง DELETE หรือ UPDATE จะถูกดำเนินการเมื่อทริกเกอร์ระดับบันทึก (ROW) เริ่มทำงาน ตัวแปร OLD ใช้ได้เฉพาะกับ DELETE และ UPDATE เท่านั้น ฟิลด์บันทึกเก่าเป็นแบบอ่านอย่างเดียวและไม่สามารถแก้ไขได้
ทีจี_NAMEชื่อชื่อของทริกเกอร์ที่ยิง
TG_WHENข้อความคำสั่ง BEFORE หรือ AFTER ขึ้นอยู่กับว่าทริกเกอร์ที่ระบุในคำจำกัดความเริ่มทำงานเมื่อใด
TG_LEVELข้อความสตริง ROW หรือ STATEMENT ขึ้นอยู่กับระดับทริกเกอร์ที่ระบุในคำจำกัดความ
TG_OPข้อความสตริง INSERT, UPDATE หรือ DELETE ขึ้นอยู่กับการดำเนินการที่ทำให้ทริกเกอร์เริ่มทำงาน
TG_RELIDออยด์ตัวระบุวัตถุของตารางที่ทริกเกอร์เริ่มทำงาน
TG_RELNAMEชื่อชื่อของตารางที่ทริกเกอร์เริ่มทำงาน

ไปยังแต่ละฟิลด์ของเรกคอร์ด ใหม่และ เก่าในขั้นตอนทริกเกอร์จะมีการจัดการดังนี้ NEW.names, OLD.rg

ตัวอย่างทริกเกอร์ PostgreSQL

นำไปใช้ในตัวอย่าง ระบบที่เรียบง่ายการบันทึกผู้ใช้ จะตรวจสอบตารางผู้ใช้และบันทึกการเปลี่ยนแปลงทั้งหมดในตารางการบันทึก ตัวอย่างเช่น เราจะสร้างตารางแบบง่าย

ตารางผู้ใช้:

สร้างตาราง "public".users (id int ไม่ใช่ null ชื่อ varchar (64) ข้อ จำกัด คีย์หลัก pkUsersID (id));

ตารางการบันทึก

สร้างตาราง "public".logs (varchar ข้อความ (256) การประทับเวลาข้อมูลโดยไม่มีเขตเวลา)

ฟังก์ชั่นทริกเกอร์

สร้างหรือแทนที่ฟังก์ชัน "public".add_to_log() ส่งคืนทริกเกอร์เป็น $$ ประกาศ v_action varchar(30);

v_user วาร์ชาร์(64); v_retstr วาร์ชาร์(256); เริ่มต้น ถ้า TG_OP = "INSERT" จากนั้น v_user = NEW.name; v_action:= "เพิ่มผู้ใช้ใหม่"; v_retstr:= v_action || v_ผู้ใช้; INSERT INTO "public".logs(ข้อความ, ข้อมูล) ค่า (v_retstr, NOW()); TG_OPกลับมาใหม่;

ELSIF TG_OP = "อัปเดต" จากนั้น v_user = NEW.name; ใหม่และ เก่า v_action:= "อัปเดตผู้ใช้";

v_retstr:= v_action || v_ผู้ใช้;

INSERT INTO "public".logs(ข้อความ, ข้อมูล) ค่า (v_retstr, NOW());

กลับมาใหม่;

ELSIF TG_OP = "ลบ" จากนั้น v_user = OLD.name;

v_action:= "ลบผู้ใช้";

v_retstr:= v_action || v_ผู้ใช้;

INSERT INTO "public".logs(ข้อความ, ข้อมูล) ค่า (v_retstr, NOW());

คืนความเก่า;<список_псевдонимов>เอนดิฟ; จบ; $$ ภาษา plpgsql;

ข้อจำกัดทริกเกอร์ที่เป็นทางเลือกสามารถรวมไว้ในข้อความการสร้างทริกเกอร์โดยการกำหนดนิพจน์บูลีน SQL ในวลี เมื่อไร- นิพจน์ในส่วนคำสั่ง WHEN ได้รับการทดสอบสำหรับแต่ละแถวที่ได้รับผลกระทบจากทริกเกอร์ หากผลลัพธ์ของนิพจน์เป็น TRUE เนื้อหาของทริกเกอร์จะถูกดำเนินการ หากนิพจน์เป็น FALSE หรือ NULL เนื้อหาทริกเกอร์จะไม่ถูกดำเนินการ นิพจน์ในส่วนคำสั่ง WHEN ต้องเป็นนิพจน์ SQL ไม่ใช่นิพจน์ PL/SQL และไม่สามารถรวมแบบสอบถามย่อยได้

อ้างอิง

ตัวเลือกการอ้างอิงสามารถใช้ในส่วนเนื้อหาของทริกเกอร์เพื่อหลีกเลี่ยงความขัดแย้งระหว่างชื่อความสัมพันธ์และชื่อตารางในกรณีที่ตารางชื่อ "เก่า" หรือ "ใหม่" สถานการณ์นี้เกิดขึ้นไม่บ่อยนักและแทบไม่เคยใช้ตัวเลือกนี้เลย

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

ทริกเกอร์ก่อน CREATE TRIGGER trg_dummy ก่อนอัปเดตในการอ้างอิงใหม่ ใหม่เป็นใหม่ล่าสุดสำหรับแต่ละแถว BEGIN:newest.field2:= TO_CHAR (:newest.field1); จบ;

ผู้ดำเนินการ ใหม่เปลี่ยนชื่อเป็นตัวเลือกการใช้ใหม่ล่าสุด อ้างอิงแล้วนำไปใช้ในตัวไกปืน

ภาคแสดงแบบมีเงื่อนไข

หากทริกเกอร์สามารถดำเนินการได้ด้วยคำสั่ง DML มากกว่าหนึ่งประเภท (เช่น "INSERT OR DELETE OR UPDATE") คำสั่งนั้นก็สามารถนำมาใช้ในเนื้อความของทริกเกอร์ได้ การใส่, กำลังลบและ กำลังอัปเดตเพื่อรันโค้ดส่วนต่างๆ ขึ้นอยู่กับเงื่อนไข ในโค้ดภายในเนื้อหาทริกเกอร์ คุณสามารถใช้เงื่อนไขต่อไปนี้:

หากใส่แล้ว - - เอนดิฟ; หากอัปเดตแล้ว - - เอนดิฟ;

จะตรงตามเงื่อนไขแรกในกรณีที่ทริกเกอร์เริ่มทำงานเมื่อมีการแทรกแถวลงในตาราง เงื่อนไขที่สองจะเป็นไปตามเมื่อมีการอัปเดตแถวของตาราง

ในตัวดำเนินการ กำลังอัปเดตคุณสามารถใช้เงื่อนไขเพิ่มเติมเพื่อตรวจสอบชื่อของคอลัมน์ที่กำลังอัปเดตได้ ตามตัวอย่าง ให้พิจารณาโค้ดต่อไปนี้ โดยที่เนื้อหาจะถูกดำเนินการหากส่วนคำสั่ง UPDATE ที่ทำให้เกิดทริกเกอร์อัปเดตคอลัมน์ SAL:

หากอัปเดต ("SAL") แล้ว - - เอนดิฟ;

ออราเคิล ทำให้เกิดการปิดเครื่องการรวม

ใน Oracle ทริกเกอร์สามารถปิดใช้งานได้ชั่วคราวหากเกิดเงื่อนไขข้อใดข้อหนึ่งต่อไปนี้:

  • ไม่สามารถเข้าถึงวัตถุที่อ้างอิงโดยทริกเกอร์
  • จำเป็นต้องโหลดข้อมูลจำนวนมากโดยไม่ต้องเรียกทริกเกอร์
  • คุณต้องโหลดข้อมูลลงในตารางโดยไม่ต้องเรียกใช้ทริกเกอร์

ทริกเกอร์จะเปิดใช้งานตามค่าเริ่มต้นเมื่อถูกสร้างขึ้น หากต้องการปิดใช้งานทริกเกอร์ คุณต้องใช้คำสั่ง เปลี่ยนทริกเกอร์พร้อมตัวเลือก ปิดการใช้งาน- หากต้องการเปิดใช้งานทริกเกอร์ ให้ใช้คำสั่ง ALTER TRIGGER พร้อมตัวเลือก เปิดใช้งาน- คุณสามารถปิดการใช้งานทริกเกอร์ทั้งหมดที่เกี่ยวข้องกับตารางพร้อมกันได้โดยใช้คำสั่ง แก้ไขตารางพร้อมตัวเลือก ปิดการใช้งานทริกเกอร์ทั้งหมด.

ปิดการใช้งานทริกเกอร์ ALTER TRIGGER TRG_Orders_INS DISABLE; -- เชื่อมต่อทริกเกอร์ ALTER TRIGGER TRG_Orders_INS ENABLE; -- ปิดการใช้งานทริกเกอร์ตารางทั้งหมด แก้ไขคำสั่งตาราง ปิดการใช้งานทริกเกอร์ทั้งหมด;

หากต้องการเปิดใช้งานหรือปิดใช้งานทริกเกอร์โดยใช้คำสั่ง ALTER TABLE คุณต้องเป็นเจ้าของตารางหรือมีสิทธิ์ที่เหมาะสม

ตัวอย่างทริกเกอร์ของ Oracle

เครื่องกำเนิดลำดับ สร้างลำดับ seqID; -- ตารางผู้ใช้ สร้างผู้ใช้ตาราง (id int PRIMARY KEY ไม่ใช่ null ชื่อ varchar (50) โทรศัพท์ varchar (15) วันที่ dt); -- ทริกเกอร์แทรกระบุรหัสบันทึกที่สร้างหรือแทนที่ทริกเกอร์ trgAutonumber ก่อนที่จะแทรกผู้ใช้ -- ทริกเกอร์ก่อนสำหรับแต่ละแถวเริ่มต้นเลือก seqID.NEXTVAL เป็น: new.id จากคู่; จบ; -- ทริกเกอร์แทรกระบุวันที่บันทึก สร้างหรือแทนที่ทริกเกอร์ trgDate ก่อนที่จะแทรกบน ผู้ใช้ทริกเกอร์ก่อน สำหรับแต่ละแถวเริ่มต้น ถ้า: old.dt เป็นโมฆะ แล้ว: new.dt:= current_date;

สิ้นสุดถ้า; สิ้นสุด trgDate; ในตัวอย่างต่อไปนี้ ทริกเกอร์ trgDepartmentst_del_cascade ดำเนินการลบเรกคอร์ดแบบเรียงซ้อนทริกเกอร์ลบ CASCADE - ทริกเกอร์ที่เชื่อมต่อกับตารางแผนกจะใช้การดำเนินการอ้างอิง DELETE CASCADEคีย์หลัก

ตาราง deptID:

ทริกเกอร์หลังจากสร้างหรือแทนที่ทริกเกอร์ trgDepartmentst_del_cascade หลังจากลบบนแผนกสำหรับแต่ละแถว BEGIN /* หลังจากลบแถวออกจากตาราง Departments แล้ว ให้ลบแถวทั้งหมดออกจากตาราง Employees ที่มีค่า deptID เหมือนกัน */ ลบออกจากพนักงาน โดยที่ Employee.deptID = :old.deptID; จบ; หมายเหตุ: โดยปกติจะเป็นรหัสสำหรับลบน้ำตก

รวมกับรหัสสำหรับ UPDATE SET NULL หรือ UPDATE SET DEFAULT เพื่อพิจารณาทั้งการอัปเดตและการลบในทริกเกอร์เดียว

การสร้างเครื่องกำเนิดไฟฟ้า

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

การสร้างเครื่องกำเนิดไฟฟ้า:<Имя генератора>

สร้างเครื่องกำเนิดไฟฟ้า

ค่าเริ่มต้นระบุโดยคำสั่ง:<Имя генератора>ชุดเครื่องกำเนิดไฟฟ้า<Начальное значение (целое число)>

ถึง

สร้างเครื่องกำเนิดไฟฟ้า GenStore

ตั้งค่า GENERATOR GenStore เป็น 1

ตัวสร้างที่สร้างขึ้นนั้นเข้าถึงได้โดยใช้ฟังก์ชัน<Имя генератора>, <Шаг>)


ทริกเกอร์คือขั้นตอนที่อยู่บนเซิร์ฟเวอร์ฐานข้อมูลและจะถูกเรียกโดยอัตโนมัติเมื่อมีการแก้ไขบันทึกฐานข้อมูล เช่น เมื่อคอลัมน์มีการเปลี่ยนแปลงหรือเมื่อมีการลบหรือเพิ่ม ซึ่งแตกต่างจากขั้นตอนการจัดเก็บ ทริกเกอร์ไม่สามารถเรียกจากแอปพลิเคชันไคลเอ็นต์ และคุณไม่สามารถส่งพารามิเตอร์ไปยังทริกเกอร์หรือรับผลลัพธ์จากทริกเกอร์เหล่านั้นได้

การสร้างทริกเกอร์:

สร้างทริกเกอร์<>สำหรับ<>

(ก่อน | หลัง)

(อัปเดต | แทรก | ลบ)

เช่น<Тело триггера>

ตัวอธิบายที่ใช้งานอยู่ | INACTIVE กำหนดว่าทริกเกอร์ทำงานทันทีหลังจากสร้างขึ้นหรือไม่ ค่าเริ่มต้นคือ ใช้งานอยู่

ก่อนคำอธิบาย | AFTER ระบุช่วงเวลาที่ทริกเกอร์เริ่มทำงานก่อนหรือหลังการเกิดเหตุการณ์ที่เกี่ยวข้องซึ่งเกี่ยวข้องกับการเปลี่ยนแปลงบันทึก

คำอธิบาย UPDATE | แทรก | DELETE กำหนดว่าเหตุการณ์ใดที่ทริกเกอร์ทริกเกอร์ - เมื่อแก้ไข เพิ่ม หรือลบบันทึก

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

การลบทริกเกอร์:

ปล่อยทริกเกอร์<Имя триггера>

การเปลี่ยนแปลงทริกเกอร์:

ในการเข้าถึงค่าคอลัมน์ จะใช้คำแนะนำการจัดรูปแบบ:

เก่า.<Имя столбца>- หมายถึงของเก่า (ก่อนที่จะมีการเปลี่ยนแปลง) ค่าคอลัมน์,

ใหม่.<Имя столбца>- อ้างถึงค่าใหม่ (หลังการเปลี่ยนแปลง) ของคอลัมน์

การสร้างทริกเกอร์เพื่อเพิ่มค่าที่ไม่ซ้ำให้กับคอลัมน์หลัก

สร้างที่เก็บตาราง

(S_Code จำนวนเต็มไม่เป็นโมฆะ

คีย์หลัก(S_Code));

ถึง

สร้างเครื่องกำเนิดไฟฟ้า GenStore

สร้าง TRIGGER CodeStore สำหรับร้านค้า

ใหม่.S_Code = GEN_ID(GenStore, 1);

เมื่อเพิ่มลงในตารางแล้ว เก็บใหม่บันทึก คอลัมน์คีย์ S_Code ของบันทึกนั้นจะได้รับการกำหนดค่าเฉพาะโดยอัตโนมัติ สามารถทำได้โดยการเรียก GEN_ID ไปยังตัวสร้าง GenStore


การดำเนินการลบเรคคอร์ดแบบเรียงซ้อนโดยใช้ทริกเกอร์

สร้างที่เก็บตาราง

(S_Code จำนวนเต็มไม่เป็นโมฆะ

คีย์หลัก(S_Code));

สร้างการ์ดตาราง

(C_Code จำนวนเต็มไม่เป็นโมฆะ

C_Code2 จำนวนเต็มไม่เป็นโมฆะ

คีย์หลัก (C_Code));

สร้างทริกเกอร์ DeleteStore สำหรับร้านค้า

ลบออกจากการ์ด โดยที่ Store.S_Code = Cards.C_Code2;

หลังจากลบรายการในตาราง Store รายการที่เกี่ยวข้องทั้งหมดในตารางการ์ดจะถูกลบโดยอัตโนมัติ

ความคิดเห็น: ตารางไม่ควรอยู่ภายใต้ข้อจำกัด Referential Integrity ที่ตั้งค่าไว้ที่ฟิสิคัลเลเยอร์

อัปเดตคอลัมน์ลิงก์ ( คอลัมน์สำคัญ) ของตารางที่เชื่อมโยง ซึ่งประกอบด้วยความจริงที่ว่าเมื่อค่าของคอลัมน์ลิงก์ของตารางหลักเปลี่ยนแปลง ค่าของคอลัมน์ลิงก์ของบันทึกที่เกี่ยวข้องทั้งหมดของตารางรองจะเปลี่ยนไปตามนั้น

สร้าง TRIGGER ChangeStore สำหรับร้านค้า

ถ้า(OLD.S_Code<>ใหม่.S_Code)

จากนั้นอัปเดตการ์ด

SET C_Code2 = ใหม่.S_Code

โดยที่ C_Code2 = OLD.S_Code;

เมื่อคุณเปลี่ยนคอลัมน์ S_Code ที่ใช้เชื่อมโยงตารางหลักของ Store กับตารางย่อยของการ์ด ค่าในคอลัมน์ลิงก์ C_Code2 ของบันทึกที่เกี่ยวข้องในตารางย่อยจะเปลี่ยนโดยอัตโนมัติ

เพื่อให้คอลัมน์ตารางหลักสามารถแก้ไขได้ จะต้องไม่สร้างคีย์สำหรับคอลัมน์นั้น