Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर ट्रिगर:समझ और विकल्प

SQL सर्वर ट्रिगर एक विशेष प्रकार की संग्रहीत कार्यविधियाँ हैं जो किसी विशिष्ट डेटाबेस सर्वर में कोई घटना होने पर स्वचालित रूप से निष्पादित होती हैं। SQL सर्वर हमें दो मुख्य प्रकार के ट्रिगर प्रदान करता है:DML ट्रिगर और डीडीएल ट्रिगर डीडीएल ट्रिगर विभिन्न डेटा डेफिनिशन लैंग्वेज (डीडीएल) घटनाओं के जवाब में सक्रिय हो जाएंगे, जैसे क्रिएट, ऑल्टर, ड्रॉप, ग्रांट, डेनी और रिवोक टी-एसक्यूएल स्टेटमेंट्स को निष्पादित करना। DDL ट्रिगर इन परिवर्तनों को डेटाबेस को प्रभावित करने से रोककर DDL क्रियाओं का जवाब दे सकता है, इन DDL क्रियाओं के जवाब में एक अन्य क्रिया कर सकता है या डेटाबेस के विरुद्ध निष्पादित इन परिवर्तनों को रिकॉर्ड कर सकता है।

SQL सर्वर DML ट्रिगर एक विशेष प्रकार की संग्रहीत कार्यविधियाँ हैं, जिन्हें डेटाबेस तालिका पर क्रियाओं के अनुक्रम को निष्पादित करने के लिए डिज़ाइन किया गया है, जिसमें ट्रिगर संलग्न होता है, जब डेटा मैनिपुलेशन लैंग्वेज (DML) ईवेंट, जैसे INSERT, UPDATE या DELETE कार्रवाई, डेटाबेस तालिकाओं या दृश्यों की सामग्री को संशोधित करने के लिए होती है, भले ही तालिका पंक्तियाँ प्रभावित हों या नहीं। ट्रिगर संग्रहीत प्रक्रियाओं से भिन्न होते हैं जिसमें पूर्वनिर्धारित डेटा संशोधन होने पर ट्रिगर स्वचालित रूप से सक्रिय हो जाते हैं। डीएमएल ट्रिगर्स का उपयोग डेटा अखंडता को बनाए रखने और कंपनी के व्यापार नियमों को लागू करने के लिए किया जा सकता है, जैसे कि टेबल चेक और विदेशी कुंजी बाधाओं की कार्यक्षमता, ऑडिटिंग प्रक्रियाओं और अन्य डीएमएल क्रियाओं को निष्पादित करके। आप अन्य तालिकाओं को क्वेरी करने और जटिल T-SQL क्वेरी करने के लिए DML ट्रिगर का उपयोग कर सकते हैं।

यदि ट्रिगर सक्रिय हो जाता है, तो एक विशेष प्रकार की वर्चुअल टेबल जिसे सम्मिलित . कहा जाता है और हटाया गया संशोधन से पहले और बाद में डेटा मानों को रखने के लिए तालिकाओं का उपयोग किया जाएगा। ट्रिगर स्टेटमेंट उसी लेन-देन के दायरे में काम करेगा जो ट्रिगर को सक्रिय करता है। इसका मतलब है कि जब तक ट्रिगर स्टेटमेंट सफलतापूर्वक पूरा नहीं हो जाता, तब तक लेनदेन पूरी तरह से प्रतिबद्ध नहीं होगा। दूसरी ओर, यदि ट्रिगर स्टेटमेंट विफल हो जाता है, तो लेन-देन वापस ले लिया जाएगा।

DML ट्रिगर दो प्रकार के होते हैं:बाद या के लिए ट्रिगर और इसके बजाय चालू कर देना। AFTER ट्रिगर को INSERT, UPDATE या DELETE क्रिया करने के बाद सक्रिय और निष्पादित किया जाएगा जो इसे सफलतापूर्वक सक्रिय करता है। साथ ही, ट्रिगर को सक्रिय करने से पहले किसी भी संदर्भात्मक कैस्केड कार्रवाई और बाधा जांच को सफल होना चाहिए। AFTER ट्रिगर को केवल तालिका स्तर पर परिभाषित किया जा सकता है, बिना किसी संभावना के इसे विचारों पर परिभाषित किया जा सकता है। ट्रिगर के INSTEAD का उपयोग उस क्रिया के कथन को ओवरराइड करने के लिए किया जाता है जो ट्रिगर में दिए गए कथन के साथ ट्रिगर को सक्रिय करता है, जब कोई व्यक्ति किसी विशिष्ट नीति को तोड़ने वाली कार्रवाई करने की कोशिश कर रहा होता है, जैसे कि अद्यतन करना एक महत्वपूर्ण वित्तीय कॉलम या परिवर्तन करने से पहले ऑडिट तालिका में परिवर्तन लिखना। ट्रिगर के बजाय आपको एक बैच क्वेरी के एक हिस्से को अस्वीकार करने और उस बैच के दूसरे भाग को सफलतापूर्वक निष्पादित करने की संभावना के अलावा, कई तालिकाओं से डेटा को संदर्भित करने वाले विचारों से डेटा डालने, अपडेट करने या हटाने की अनुमति देता है। ट्रिगर के INSTEAD का उपयोग उन अद्यतन करने योग्य दृश्यों के साथ नहीं किया जा सकता है जिनमें CHECK OPTION के साथ है और उन तालिकाओं में एक संदर्भात्मक संबंध है जो DELETE या UPDATE पर कैस्केड क्रियाओं को निर्दिष्ट करता है।

ट्रिगर्स पर सैद्धांतिक रूप से चर्चा करने के बाद, हम यह दिखाना शुरू करेंगे कि हम व्यावहारिक रूप से क्या चर्चा करते हैं। आगामी डेमो में, हम उन विभिन्न स्थितियों को दिखाएंगे जिनमें हम SQL सर्वर ट्रिगर से लाभ उठा सकते हैं।

बाद... DML ट्रिगर

मान लें कि हमें एक विशिष्ट तालिका पर किए गए डीएमएल कार्यों को ट्रैक करने और इन लॉग को इतिहास तालिका में लिखने की आवश्यकता है, जहां सम्मिलित, अद्यतन या हटाए गए रिकॉर्ड की आईडी और की जाने वाली कार्रवाई इतिहास तालिका में लिखी जाएगी। नीचे दिए गए CREATE TABLE T-SQL स्टेटमेंट का उपयोग सोर्स और हिस्ट्री टेबल दोनों बनाने के लिए किया जा सकता है:

टेबल ट्रिगर डेमो_पेरेंट बनाएं (आईडी INT पहचान (1,1) प्राथमिक कुंजी, Emp_First_name VARCHAR (50), Emp_Last_name VARCHAR (50), Emp_Salary INT) GOCREATE TABLE TriggerDemo_History (आईडी INT पहचान (1,1) प्राथमिक कुंजी कुंजी , परफॉर्मेडएक्शन VARCHAR (50), )GO

INSERT ऑपरेशन को ट्रैक करने के लिए, हम एक DML ट्रिगर बनाएंगे जिसे पैरेंट टेबल पर INSERT ऑपरेशन करने के बाद निकाल दिया जाएगा। यह ट्रिगर वर्चुअल सम्मिलित तालिका से उस मूल तालिका में अंतिम सम्मिलित आईडी मान पुनर्प्राप्त करेगा, जैसा कि नीचे दिए गए ट्रिगर टी-एसक्यूएल कथन बनाएं:

इन्सर्ट के बाद ट्रिगर बनाएंTriggerON TriggerDemo_Parentबाद में TriggerDemo_History VALUES में INSERTASINSERT करें ((सम्मिलित शीर्ष 1 का चयन करें। सम्मिलित से आईडी), 'सम्मिलित करें')जाओ

DELETE ऑपरेशन को ट्रैक करना DML ट्रिगर बनाकर प्राप्त किया जा सकता है जिसे पैरेंट टेबल पर DELETE ऑपरेशन करने के बाद निकाल दिया जाता है। फिर से, ट्रिगर वर्चुअल डिलीट टेबल से उस पैरेंट टेबल से पिछले हटाए गए रिकॉर्ड के आईडी मान को पुनः प्राप्त करेगा, जैसा कि नीचे दिए गए CREATE TRIGGER T-SQL स्टेटमेंट में है:

डिलीट के बाद ट्रिगर बनाएंTriggerON TriggerDemo_Parentबाद में DELETEASINSERT INTO TriggerDemo_History VALUES ((चुनें टॉप 1 डिलीट किया गया। डिलीट से आईडी), 'डिलीट')जाओ

अंत में, हम एक DML ट्रिगर बनाकर UPDATE ऑपरेशन को भी ट्रैक करेंगे जिसे पैरेंट टेबल पर UPDATE ऑपरेशन करने के बाद निकाल दिया जाएगा। इस ट्रिगर के भीतर, हम वर्चुअल सम्मिलित तालिका से उस मूल तालिका से अंतिम अद्यतन आईडी मान पुनर्प्राप्त करेंगे, इस बात को ध्यान में रखते हुए कि अद्यतन प्रक्रिया रिकॉर्ड को हटाकर और अद्यतन मानों के साथ एक नया रिकॉर्ड डालने के द्वारा की जाती है, जैसा कि क्रिएट ट्रिगर में होता है नीचे टी-एसक्यूएल स्टेटमेंट:

अपडेट के बाद ट्रिगर बनाएंTriggerON TriggerDemo_Parentअद्यतन के बाद TriggerDemo_History VALUES में INSERT करें ((सम्मिलित शीर्ष 1 का चयन करें। सम्मिलित से आईडी चुनें), 'अपडेट करें')जाओ

टेबल और ट्रिगर अब हमारे परीक्षण के लिए तैयार हैं। यदि आप नीचे दिए गए INSERT INTO T-SQL स्टेटमेंट का उपयोग करके पैरेंट टेबल में एक नया रिकॉर्ड डालने का प्रयास करते हैं:

ट्रिगरडेमो_पैरेंट वैल्यू ('एएए','बीबीबी',500) में डालें

फिर पिछले INSERT स्टेटमेंट को निष्पादित करके उत्पन्न निष्पादन योजना की जाँच करके, आप देखेंगे कि दो इंसर्ट ऑपरेशन किए जाएंगे, जिससे दो टेबल प्रभावित होंगे; INSERT कथन में निर्दिष्ट मानों के साथ मूल तालिका और INSERT ट्रिगर को सक्रिय करने के कारण इतिहास तालिका, जैसा कि नीचे निष्पादन योजना में दिखाया गया है:

यह तब भी स्पष्ट होता है जब आप नीचे दिए गए सेलेक्ट स्टेटमेंट का उपयोग करके पैरेंट और हिस्ट्री टेबल दोनों में डाले गए डेटा की जांच करते हैं:

चुनें * TriggerDemo_ParentGOSELECT से * TriggerDemo_History से

जहां INSERT स्टेटमेंट में निर्दिष्ट मान पैरेंट टेबल में डाले जाएंगे, और इंसर्ट लॉग जिसमें इंसर्ट किए गए रिकॉर्ड की आईडी और किए गए ऑपरेशन को इतिहास तालिका में डाला जाएगा, जैसा कि नीचे दिए गए परिणाम में दिखाया गया है:

अब, यदि आप नीचे दिए गए UPDATE T-SQL स्टेटमेंट का उपयोग करके पैरेंट टेबल में मौजूदा रिकॉर्ड को अपडेट करने का प्रयास करते हैं:

अपडेट TriggerDemo_Parent SET Emp_Salary=550 WHERE ID=1

और पिछले अद्यतन विवरण को निष्पादित करके उत्पन्न निष्पादन योजना की जांच करें, आप देखेंगे कि अद्यतन ऑपरेशन के बाद दो अलग-अलग तालिकाओं को प्रभावित करने वाला एक सम्मिलित ऑपरेशन होगा; मूल तालिका को अद्यतन विवरण में निर्दिष्ट मान के साथ अद्यतन किया जाएगा और अद्यतन के बाद ट्रिगर को सक्रिय करने के कारण इतिहास तालिका में सम्मिलित करें कार्रवाई, जैसा कि नीचे निष्पादन योजना में दिखाया गया है:

नीचे दिए गए सेलेक्ट स्टेटमेंट का उपयोग करके पैरेंट और हिस्ट्री टेबल रिकॉर्ड दोनों की जांच करना:

चुनें * TriggerDemo_ParentGOSELECT से * TriggerDemo_History से

आप देखेंगे कि अपडेट स्टेटमेंट मूल तालिका में Emp_Salary मान को UPDATE स्टेटमेंट में निर्दिष्ट मान के साथ संशोधित करेगा, और अपडेट लॉग जिसमें अपडेट किए गए रिकॉर्ड की आईडी और किए गए ऑपरेशन को इतिहास तालिका में डाला जाएगा, जैसा कि नीचे दिए गए परिणाम में दिखाया गया है:

AFTER DML ट्रिगर के अंतिम परिदृश्य में, हम नीचे दिए गए DELETE T-SQL स्टेटमेंट का उपयोग करके पैरेंट टेबल से मौजूदा रिकॉर्ड के विलोपन को ट्रैक करेंगे:

TriggerDemo_Parent से हटाएं जहां आईडी=1

फिर पिछले DELETE स्टेटमेंट को निष्पादित करके उत्पन्न निष्पादन योजना की जाँच करें, आप देखेंगे कि DELETE ऑपरेशन के बाद इंसर्ट ऑपरेशन होगा, जो दो अलग-अलग तालिकाओं को प्रभावित करेगा; पैरेंट टेबल जिसमें से DELETE स्टेटमेंट के WHERE क्लॉज में प्रदान की गई आईडी के साथ रिकॉर्ड को हटा दिया जाएगा और AFTER DELETE ट्रिगर को फायर करने के कारण हिस्ट्री टेबल में इंसर्ट ऑपरेशन, जैसा कि नीचे दी गई निष्पादन योजना में दिखाया गया है:

यदि आप नीचे दिए गए सेलेक्ट स्टेटमेंट का उपयोग करके पैरेंट और हिस्ट्री टेबल रिकॉर्ड दोनों की जांच करते हैं:

चुनें * TriggerDemo_ParentGOSELECT से * TriggerDemo_History से

आप देखेंगे कि 1 के बराबर आईडी मान वाला रिकॉर्ड DELETE स्टेटमेंट में प्रदान की गई मूल तालिका से हटा दिया गया था, और हटाए गए रिकॉर्ड और किए गए ऑपरेशन की आईडी वाले डिलीट लॉग को इतिहास तालिका में डाला जाएगा। , जैसा कि नीचे दिए गए परिणाम में दिखाया गया है:

के बजाय... DML ट्रिगर

दूसरे प्रकार का DML ट्रिगर INSTEAD OF DML ट्रिगर है। जैसा कि पहले उल्लेख किया गया है, INSTEAD OF ट्रिगर उस क्रिया के कथन को ओवरराइड कर देगा जो ट्रिगर में दिए गए कथन के साथ ट्रिगर को सक्रिय करता है। मान लें कि हमें उन DML क्रियाओं को लॉग करने की आवश्यकता है जो उपयोगकर्ता किसी विशिष्ट तालिका पर प्रदर्शन करने की कोशिश कर रहे हैं, उन्हें उस क्रिया को करने की अनुमति दिए बिना। नीचे दिए गए CREATE TABLE T-SQL स्टेटमेंट का उपयोग स्रोत और वैकल्पिक टेबल दोनों बनाने के लिए किया जा सकता है:

टेबल ट्रिगर डेमो_न्यूपैरेंट बनाएं (आईडी INT पहचान (1,1) प्राथमिक कुंजी, Emp_First_name VARCHAR (50), Emp_Last_name VARCHAR (50), Emp_Salary INT) GOCREATE TABLE TriggerDemo_InsteadParent (आईडी INT पहचान (1,1) प्राथमिक कुंजी , परफॉर्मेडएक्शन VARCHAR (50), )GO

दो टेबल बनाने के बाद, हम नीचे दिए गए INSERT INTO स्टेटमेंट का उपयोग करके अपने डेमो के लिए सोर्स टेबल में एक रिकॉर्ड डालेंगे:

ट्रिगरडेमो_न्यूपैरेंट वैल्यू ('एए','बीबी', 500) में डालें

इस डेमो के लिए, हम INSERT, UPDATE और DELETE ऑपरेशंस को ओवरराइड करने के लिए तीन ट्रिगर बनाएंगे। पहले ट्रिगर का उपयोग पैरेंट टेबल पर किसी भी इंसर्ट ऑपरेशन और वैकल्पिक टेबल में बदलने वाले लॉग को रोकने के लिए किया जाएगा। ट्रिगर नीचे दिए गए CREATE TRIGGER T-SQL स्टेटमेंट का उपयोग करके बनाया गया है:

इसके बजाय TRIGGER बनाएंOfInsertTriggerON TriggerDemo_NewParentInSERTASINSERT INTO TriggerDemo_InsteadParent VALUES ((चुनें शीर्ष 1 डाला गया। आईडी से डाला गया), 'नई आईडी डालने की कोशिश कर रहा है') जाओ

दूसरे ट्रिगर का उपयोग पैरेंट टेबल पर किसी भी अपडेट ऑपरेशन और वैकल्पिक टेबल में बदलने वाले लॉग को रोकने के लिए किया जाता है। यह ट्रिगर निम्नानुसार बनाया गया है:

इसके बजाय TRIGGER बनाएंOfUpdateTriggerON TriggerDemo_NewParentअद्यतन के बजाय TriggerDemo_InsteadParent VALUES में डालें ((सम्मिलित शीर्ष 1 का चयन करें। सम्मिलित से आईडी चुनें), 'मौजूदा आईडी को अपडेट करने का प्रयास कर रहा है')जाओ

अंतिम ट्रिगर का उपयोग पैरेंट टेबल पर किसी भी डिलीट ऑपरेशन और वैकल्पिक टेबल में बदलने वाले लॉग को रोकने के लिए किया जाएगा। यह ट्रिगर इस प्रकार बनाया गया है:

इसके बजाय TRIGGER बनाएंऑफ़DeleteTriggerON TriggerDemo_NewParentइसके बजाय DELETEASINSERT INTO TriggerDemo_InsteadParent VALUES ((चुनें शीर्ष 1 डाला गया। आईडी से सम्मिलित किया गया), 'मौजूदा आईडी को हटाने की कोशिश कर रहा है')जाओ

दो टेबल और तीन ट्रिगर अब तैयार हैं। यदि आप नीचे दिए गए INSERT INTO T-SQL स्टेटमेंट का उपयोग करके पैरेंट टेबल में एक नया मान डालने का प्रयास करते हैं:

ट्रिगरडेमो_न्यूपैरेंट वैल्यू ('सीसीसी','डीडीडी',500) में डालें

फिर नीचे दिए गए सेलेक्ट स्टेटमेंट का उपयोग करके पैरेंट और वैकल्पिक टेबल रिकॉर्ड दोनों की जांच करें:

चुनें * TriggerDemo_NewParentGOSELECT से * TriggerDemo_InsteadParent से

इस तथ्य के कारण कि हमारे पास पैरेंट टेबल में INSTEAD OF INSERT ट्रिगर है, आप परिणाम से देखेंगे कि पैरेंट टेबल में कोई नया रिकॉर्ड नहीं डाला गया है, और इन्सर्ट ऑपरेशन के लिए एक लॉग वैकल्पिक टेबल में डाला गया है, जैसा कि दिखाया गया है नीचे दिए गए परिणाम में:

नीचे दिए गए UPDATE T-SQL स्टेटमेंट का इस्तेमाल करके पैरेंट टेबल में मौजूदा रिकॉर्ड को अपडेट करने की कोशिश की जा रही है:

अपडेट TriggerDemo_NewParent SET Emp_Salary=550 WHERE ID=1

फिर नीचे दिए गए सेलेक्ट स्टेटमेंट का उपयोग करके पैरेंट और वैकल्पिक टेबल रिकॉर्ड दोनों की जाँच करना:

चुनें * TriggerDemo_NewParentGOSELECT से * TriggerDemo_InsteadParent से

आप परिणाम से देखेंगे कि पेरेंट तालिका से आईडी मान के बराबर 1 के साथ रिकॉर्ड का Emp_Salary मान नहीं बदला जाएगा, और अद्यतन ऑपरेशन के लिए लॉग को वैकल्पिक तालिका में डाला गया है, क्योंकि INSTEAD OF UPDATE ट्रिगर है मूल तालिका में, जैसा कि नीचे परिणाम में दिखाया गया है:

अंत में, यदि हम नीचे दिए गए DELETE T-SQL स्टेटमेंट का उपयोग करके पैरेंट टेबल से मौजूदा रिकॉर्ड को हटाने का प्रयास करते हैं:

TriggerDemo_NewParent से हटाएं जहां आईडी=1

और नीचे दिए गए सेलेक्ट स्टेटमेंट का उपयोग करके पैरेंट और वैकल्पिक टेबल रिकॉर्ड दोनों की जांच करें:

चुनें * TriggerDemo_NewParentGOSELECT से * TriggerDemo_InsteadParent से

परिणाम से यह स्पष्ट होगा कि पैरेंट टेबल से आईडी मान के बराबर 1 के साथ रिकॉर्ड को हटाया नहीं जाएगा, और डिलीट ऑपरेशन के लिए लॉग को पैरेंट में INSTEAD OF DELETE ट्रिगर होने के कारण वैकल्पिक तालिका में डाला गया है। तालिका, जैसा कि नीचे दिए गए परिणाम में दिखाया गया है:

बाद... संदेशों के साथ DML ट्रिगर

ट्रिगर के बाद उपयोगकर्ता के लिए चेतावनी संदेश बढ़ाने के लिए भी इस्तेमाल किया जा सकता है। इस मामले में, क्वेरी एक सूचनात्मक संदेश होगी जो उस ट्रिगर को सक्रिय करने वाले कथन को निष्पादित करने से नहीं रोकेगी। आइए हम पहले बनाए गए INSTEAD OF UPDATE ट्रिगर को छोड़ दें और इसे किसी अन्य अद्यतन के बाद ट्रिगर से बदलें जो नीचे दिए गए DROP/CREATE TRIGGER T-SQL स्टेटमेंट का उपयोग करके कोई भी अपडेट ऑपरेशन करने के बाद एक चेतावनी त्रुटि उत्पन्न करेगा:

DROP TRIGGER इसके बजायUpdateTriggerCREATE TRIGGER ReminderTrigger on TriggerDemo_NewParent अद्यतन के बाद RAISERROR के रूप में ('एक अपडेट TriggerDemo_NewParent तालिका पर किया जाता है', 16, 10); जाओ 

यदि आप नीचे दिए गए UDPATE स्टेटमेंट का उपयोग करके कर्मचारी के Emp_Salary मान को 1 के बराबर आईडी मान के साथ अपडेट करने का प्रयास करते हैं:

अपडेट TriggerDemo_NewParent SET Emp_Salary=550 WHERE ID=1

संदेश . में एक त्रुटि संदेश उठाया जाएगा टैब, जिसमें बनाए गए ट्रिगर में दिया गया संदेश है, जैसा कि नीचे दिखाया गया है:

नीचे दिए गए सेलेक्ट स्टेटमेंट का उपयोग करके पैरेंट टेबल डेटा की जाँच करना:

चुनें* TriggerDemo_NewParent से

आप परिणाम से देखेंगे कि Emp_Salary सफलतापूर्वक अपडेट हो गई है, जैसा कि नीचे दिखाया गया है:

यदि आपको त्रुटि संदेश उठाने के बाद अद्यतन कार्रवाई को रोकने के लिए अद्यतन के बाद ट्रिगर की आवश्यकता है, तो रोलबैक ट्रिगर को ट्रिगर करने वाले अपडेट ऑपरेशन को रोलबैक करने के लिए ट्रिगर में स्टेटमेंट जोड़ा जा सकता है, यह याद करते हुए कि ट्रिगर और ट्रिगर को सक्रिय करने वाले स्टेटमेंट को एक ही ट्रांजैक्शन में निष्पादित किया जाएगा। इसे ALTER TRIGGER T-SQL स्टेटमेंट का उपयोग करके प्राप्त किया जा सकता है, देखें:

 वैकल्पिक ट्रिगर रिमाइंडर ट्रिगर पर ट्रिगर के रूप में अपडेट करने के बाद डेमो_न्यूपैरेंट ('ट्रिगरडेमो_न्यूपैरेंट टेबल पर एक अपडेट किया जाता है', 16, 10); रोलबैकगो 

यदि आप नीचे दिए गए UPDATE स्टेटमेंट का उपयोग करके कर्मचारी के Emp_Salary मान को 1 के बराबर आईडी से अपडेट करने का प्रयास करते हैं:

अपडेट TriggerDemo_NewParent SET Emp_Salary=700 WHERE ID=1

फिर से, संदेश . में एक त्रुटि संदेश प्रदर्शित किया जाएगा टैब, लेकिन इस बार, अद्यतन कार्रवाई पूरी तरह से वापस ले ली जाएगी, जैसा कि नीचे दिए गए त्रुटि संदेशों में दिखाया गया है:

नीचे दिए गए सेलेक्ट स्टेटमेंट का उपयोग करके सोर्स टेबल से वैल्यू चेक करना:

चुनें* TriggerDemo_NewParent से

आप देखेंगे कि Emp_Salary मान नहीं बदला है, क्योंकि अद्यतन के बाद ट्रिगर ने त्रुटि संदेश को बढ़ाने के बाद समग्र लेनदेन को वापस ले लिया, जैसा कि नीचे तालिका परिणाम में दिखाया गया है:

ट्रिगर नुकसान

SQL सर्वर ट्रिगर के सभी उल्लिखित लाभों के साथ, ट्रिगर डेटाबेस की जटिलता को बढ़ाते हैं। यदि ट्रिगर बुरी तरह से डिज़ाइन किया गया है या अधिक उपयोग किया गया है, तो यह प्रमुख प्रदर्शन मुद्दों को जन्म देगा, जैसे कि अवरुद्ध सत्र, लंबे समय तक लेन-देन के जीवन का विस्तार करने के कारण, सिस्टम पर अतिरिक्त ओवरहेड इसे हर बार INSERT, UPDATE या निष्पादित करने के कारण होता है। DELETE कार्रवाई की जाती है या इससे डेटा हानि की समस्या हो सकती है। साथ ही, डेटाबेस ट्रिगर्स को देखना और ट्रेस करना आसान नहीं है, खासकर अगर इसके बारे में कोई दस्तावेज़ीकरण नहीं है क्योंकि यह डेवलपर्स और एप्लिकेशन के लिए अदृश्य है।

ट्रिगर विकल्प ... सत्यनिष्ठा लागू करें

यदि यह पाया जाता है कि ट्रिगर आपके SQL सर्वर इंस्टेंस के प्रदर्शन को नुकसान पहुंचा रहे हैं, तो आपको उन्हें अन्य समाधानों से बदलना होगा। उदाहरण के लिए, इकाई अखंडता को लागू करने के लिए ट्रिगर्स का उपयोग करने के बजाय, इसे प्राथमिक कुंजी और अद्वितीय बाधाओं का उपयोग करके निम्नतम स्तर पर लागू किया जाना चाहिए। वही डोमेन अखंडता पर लागू होता है जिसे चेक बाधाओं के माध्यम से लागू किया जाना चाहिए, और संदर्भित अखंडता जिसे विदेशी कुंजी बाधाओं के माध्यम से लागू किया जाना चाहिए। आप DML ट्रिगर का उपयोग केवल तभी कर सकते हैं जब किसी विशिष्ट बाधा द्वारा समर्थित सुविधाएँ आपकी एप्लिकेशन आवश्यकताओं को पूरा नहीं कर सकती हैं।

आइए हम DML ट्रिगर का उपयोग करके डोमेन अखंडता को लागू करने और CHECK बाधाओं का उपयोग करने के बीच तुलना करें। मान लें कि हमें केवल Emp_Salary कॉलम में सकारात्मक मान डालने की आवश्यकता है। हम नीचे CREATE TABLE T-SQL स्टेटमेंट का उपयोग करके एक साधारण टेबल बनाने के साथ शुरू करेंगे:

टेबल कर्मचारी वेतन ट्रिगर बनाएं (आईडी INT पहचान (1,1) प्राथमिक कुंजी, Emp_First_name VARCHAR (50), Emp_Last_name VARCHAR (50), Emp_Salary INT )GO

फिर डीएमएल ट्रिगर डालने के बाद परिभाषित करें जो यह सुनिश्चित करता है कि यदि कोई उपयोगकर्ता नीचे दिए गए ट्रिगर टी-एसक्यूएल स्टेटमेंट का उपयोग करके नकारात्मक वेतन मान सम्मिलित करता है, तो लेनदेन को वापस रोल करके Emp_Salary कॉलम में एक सकारात्मक मान डालें:

इंप्लाई वेतन पर ट्रिगर TRGR_कर्मचारी वेतन बनाएं ASDECLARE @EmpSal AS INTSET @EmpSal के बाद ट्रिगर करें =(शीर्ष 1 सम्मिलित करें। Emp_Salary से सम्मिलित किया गया) IF @EmpSal<0BEGIN RAISERROR ('नकारात्मक वेतन सम्मिलित नहीं कर सकता',16,10); रोलबैकEND

तुलना के उद्देश्यों के लिए, हम उसी स्कीमा के साथ एक और सरल तालिका बनाएंगे, और नीचे दिखाए गए अनुसार Emp_Salary कॉलम में केवल सकारात्मक मानों को स्वीकार करने के लिए CREATE TABLE स्टेटमेंट के भीतर एक CHECK बाधा को परिभाषित करेंगे:

टेबल कर्मचारी वेतन बाधा बनाएं(आईडी INT पहचान (1,1) प्राथमिक कुंजी, Emp_First_name VARCHAR (50), Emp_Last_name VARCHAR (50), Emp_Salary INT CONSTRAINT EmpSal CHECK (Emp_Salary>=0) )GO

यदि आप नीचे दिए गए INSERT INTO स्टेटमेंट का उपयोग करके नीचे दिए गए रिकॉर्ड को सम्मिलित करने का प्रयास करते हैं जिसमें नकारात्मक Emp_Salary मान होता है, जिसमें एक पूर्वनिर्धारित ट्रिगर होता है:

कर्मचारी वेतन ट्रिगर मूल्यों में सम्मिलित करें('अली', 'फदी', -4)जाओ

INSERT स्टेटमेंट एक त्रुटि संदेश देने में विफल हो जाएगा, यह दिखाते हुए कि आप Emp_Salary कॉलम में एक नकारात्मक मान सम्मिलित नहीं कर सकते हैं और INSERT ट्रिगर होने के कारण समग्र लेनदेन को रोलबैक कर सकते हैं, जैसा कि नीचे दिए गए त्रुटि संदेश में दिखाया गया है:

साथ ही, यदि आप उसी रिकॉर्ड को सम्मिलित करने का प्रयास करते हैं जिसमें नकारात्मक Emp_Salary मान दूसरी तालिका में है जिसमें नीचे दिए गए INSERT INTO कथन का उपयोग करके पूर्वनिर्धारित CHECK बाधा है:

कर्मचारी वेतन बाधा मूल्यों में डालें ('अली', 'फदी', -4)

INSERT कथन फिर से विफल हो जाएगा यह दिखाते हुए कि आप उस मान को सम्मिलित करने का प्रयास कर रहे हैं जो CHECK बाधा स्थिति के साथ विरोध करता है, जैसा कि नीचे दिए गए त्रुटि संदेश में दिखाया गया है:

पिछले परिणामों से, आप देखते हैं कि ट्रिगर और CHECK बाधा दोनों विधियां आपको नकारात्मक Emp_Salary मान डालने से रोककर लक्ष्य प्राप्त करती हैं। लेकिन कौन सा बेहतर है? आइए हम प्रत्येक के लिए निष्पादन योजना भार की जाँच करके दो विधियों के प्रदर्शन की तुलना करें। दो प्रश्नों को निष्पादित करने के बाद उत्पन्न निष्पादन योजनाओं से, आप देखेंगे कि ट्रिगर विधि वजन तीन गुना है CHECK बाधा विधि वजन, जैसा कि नीचे निष्पादन योजना तुलना में दिखाया गया है:

साथ ही, प्रत्येक द्वारा खर्च किए गए निष्पादन समय की तुलना करने के लिए, आइए नीचे दिए गए T-SQL कथनों का उपयोग करके प्रत्येक को 1000 बार चलाएं:

कर्मचारी वेतन में डालेंट्रिगर मान ('अली', 'फदी', -4) 10000 कर्मचारी वेतन बाधा मान ('अली', 'फ़दी', -4) में डालें 10000 

आप देखेंगे कि ट्रिगर का उपयोग करने वाली पहली विधि में लगभग 31ms का समय लगेगा पूरी तरह से निष्पादित होने के लिए, जहां दूसरी विधि जो CHECK बाधा का उपयोग कर रही है, उसमें केवल 17ms लगेगा। , जो लगभग 0.5 बार . है ट्रिगर का उपयोग करके विधि में आवश्यक है। यह इस तथ्य के कारण है कि ट्रिगर लेन-देन के जीवन का विस्तार करेगा और एक अखंडता उल्लंघन पाए जाने पर ट्रिगर को सक्रिय करने वाली क्वेरी को रोलबैक करेगा, जिससे रोलबैक प्रक्रिया के कारण प्रदर्शन में गिरावट आती है। CHECK बाधा का उपयोग करते समय मामला अलग होता है, जहां डेटा में कोई भी संशोधन करने से पहले बाधा अपना काम करेगी, उल्लंघन के मामले में कोई रोलबैक की आवश्यकता नहीं है।

ट्रिगर विकल्प ... ऑडिटिंग

जैसा कि हमने पहले उल्लेख किया है, ट्रिगर का उपयोग किसी विशिष्ट तालिका पर किए गए परिवर्तनों को ऑडिट और ट्रैक करने के लिए भी किया जा सकता है। यदि यह ऑडिटिंग विधि आपके SQL सर्वर इंस्टेंस में प्रदर्शन में गिरावट का कारण बनती है, तो आप इसे आसानी से OUTPUT से बदल सकते हैं खंड। OUTPUT क्लॉज INSERT, UPDATE या DELETE ऑपरेशन से प्रभावित प्रत्येक पंक्ति के बारे में एक पुष्टिकरण संदेश या एक मान के रूप में जानकारी देता है जिसे ऐतिहासिक तालिका में डाला जा सकता है। OUTPUT क्लॉज विधि हमें निष्पादित कोड पर अधिक नियंत्रण प्रदान करती है, क्योंकि इसे डेटा सम्मिलन, संशोधन या विलोपन स्टेटमेंट में जब भी आप चाहें, ट्रिगर के विपरीत जोड़ा जाएगा, जिसे हमेशा निष्पादित किया जाएगा।

आइए हम डीएमएल ट्रिगर्स का उपयोग करके और OUTPUT क्लॉज का उपयोग करके डेटा प्रविष्टि और इतिहास तालिका में संशोधन के बीच तुलना करें। हम नीचे दिए गए क्रिएट टेबल टी-एसक्यूएल स्टेटमेंट का उपयोग करके नीचे प्रोडक्शन और हिस्ट्री टेबल बनाने के साथ शुरू करेंगे:

टेबल ट्रिगर डेमो_प्रोड बनाएं (आईडी INT पहचान (1,1) प्राथमिक कुंजी, Emp_First_name VARCHAR (50), Emp_Last_name VARCHAR (50), Emp_Salary INT) GOCREATE TABLE TriggerDemo_ProdHistory (आईडी INT पहचान (1,1) प्राथमिक कुंजी , प्रोडसैलेरी INT, TS DATETIME, )GO

एक बार दोनों टेबल सफलतापूर्वक बन जाने के बाद, हम INSERT, UPDATE DML ट्रिगर बनाएंगे जो इतिहास तालिका में एक रिकॉर्ड लिखेगा यदि कोई नई पंक्ति उत्पादन तालिका में डाली जाती है या मौजूदा रिकॉर्ड को CREATE TRIGGER T-SQL स्टेटमेंट का उपयोग करके संशोधित किया जाता है। नीचे:

ट्रिगर प्रोडहिस्ट्री बनाएंट्रिगरडेमो_प्रोड के बाद डालें, अपडेट करेंट्रिगरडेमो_प्रोडहिस्ट्री वैल्यू में डालें ((चुनें टॉप 1 इंसर्ट किया गया। आईडी से डाला गया), (टॉप 1 इंसर्ट किया गया चुनें। इंसर्ट से एम्प_सैलरी), GETDATE ()) GO

ट्रिगर विधि और OUTPUT क्लॉज का उपयोग करके परिवर्तनों की लॉगिंग की तुलना करने के लिए, हमें दो नई सरल तालिकाएँ बनाने की आवश्यकता है, उत्पादन और इतिहास तालिकाएँ, पिछले दो तालिकाओं के समान स्कीमा के साथ, लेकिन इस बार ट्रिगर को परिभाषित किए बिना, का उपयोग करके नीचे टेबल टी-एसक्यूएल स्टेटमेंट बनाएं:

टेबल आउटपुट डेमो_प्रोड बनाएं (आईडी INT पहचान (1,1) प्राथमिक कुंजी, Emp_First_name VARCHAR (50), Emp_Last_name VARCHAR (50), Emp_Salary INT) GOCREATE TABLE OutputDemo_ProdHistory (आईडी INT पहचान (1,1) प्राथमिक कुंजी , प्रोडसैलेरी INT, TS DATETIME, ) GO

अब चार टेबल टेस्टिंग के लिए तैयार हैं। हम पहली उत्पादन तालिका में एक रिकॉर्ड सम्मिलित करेंगे जिसमें नीचे T-SQL कथन में INSERT का उपयोग करके ट्रिगर होगा:

ट्रिगरडेमो_प्रोड मानों में डालें('एए','बीबी', 750)जाओ 

फिर हम OUTPUT क्लॉज का उपयोग करके उसी रिकॉर्ड को दूसरी प्रोडक्शन टेबल में डालेंगे। नीचे दिया गया INSERT INTO स्टेटमेंट दो इंसर्ट स्टेटमेंट के रूप में कार्य करेगा; पहला एक ही रिकॉर्ड को प्रोडक्शन टेबल में डालेगा और दूसरा इंसर्ट स्टेटमेंट OUTPUT क्लॉज के बगल में इंसर्शन लॉग को हिस्ट्री टेबल में इंसर्ट करेगा:

आउटपुट में डालेंDemo_Prod OUTPUT डाला गया। 

चार उत्पादन और इतिहास तालिकाओं में डाले गए डेटा की जाँच करते हुए, आप देखेंगे कि दोनों विधियाँ, ट्रिगर और OUTPUT विधियाँ, इतिहास तालिका में एक ही लॉग को सफलतापूर्वक और उसी तरह लिख देंगी, जैसा कि नीचे दिए गए परिणाम में दिखाया गया है:

दो प्रश्नों को निष्पादित करने के बाद उत्पन्न निष्पादन योजनाओं से, आप देखेंगे कि ट्रिगर विधि का वजन लगभग (21%+36%) 57% है कुल वजन का, जहां OUTPUT विधि वजन लगभग 43% . है , एक छोटे वजन अंतर के साथ, जैसा कि नीचे निष्पादन योजनाओं की तुलना में दिखाया गया है:

प्रत्येक विधि द्वारा उपभोग किए गए निष्पादन समय की तुलना करते समय प्रदर्शन अंतर स्पष्ट होता है, जहां ट्रिगर विधि का उपयोग करके परिवर्तनों को लॉग करने में (114+125) 239ms की खपत होगी पूरी तरह से निष्पादित होने के लिए, और OUTPUT क्लॉज विधि का उपयोग करने वाली विधि केवल 5ms की खपत करती है , जो 2% . है ट्रिगर विधि में उपयोग किए गए समय का, जैसा कि नीचे दिए गए समय सांख्यिकी से स्पष्ट रूप से दिखाया गया है:

अब पिछले परिणाम से यह स्पष्ट है कि परिवर्तनों की ऑडिटिंग के लिए ट्रिगर का उपयोग करने की तुलना में OUTPUT पद्धति का उपयोग करना बेहतर है।

उपयोगी कड़ियाँ:

  • ट्रिगर बनाएं (ट्रांजैक्ट-एसक्यूएल) https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql
  • डीएमएल ट्रिगर https://docs.microsoft.com/en-us/sql/relational-databases/triggers/dml-triggers
  • डीडीएल ट्रिगर https://docs.microsoft.com/en-us/sql/relational-databases/triggers/ddl-triggers
  • आउटपुट क्लॉज (ट्रांजैक्ट-एसक्यूएल) https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. बिना वैज्ञानिक संकेतन के SQL सर्वर में फ्लोट को वर्चर में बदलें

  2. sql सर्वर अमान्य वस्तु का नाम - लेकिन तालिकाएँ SSMS तालिका सूची में सूचीबद्ध हैं

  3. SQL सर्वर (T-SQL) में 'दिनांक' को 'डेटाटाइम' में बदलने के उदाहरण

  4. विदेशी कुंजी बाधा चक्र या एकाधिक कैस्केड पथ का कारण बन सकती है?

  5. HAS_DBACCESS () - पता लगाएं कि क्या कोई उपयोगकर्ता SQL सर्वर में किसी डेटाबेस तक पहुंच सकता है