SQL सर्वर: केवल अपने वर्तमान सत्र के लिए अपडेट के लिए ट्रिगर को अक्षम कैसे करें?


15

मैं SQL Server 2008 R2 पर काम कर रहा हूं।

मेरे पास एक टेबल लाभ है जिसमें एक AFSERT , UPDATE ट्रिगर है जिसका नाम tiu_benefit है

मैं 1 पंक्ति को अद्यतन करने के लिए इस तालिका के लिए अद्यतन विवरण लिखना चाहता हूं, लेकिन मैं इसकी आग को ट्रिगर नहीं करना चाहता। मुझे पता है कि मैं UPDATE से पहले ट्रिगर को अक्षम कर सकता हूं और फिर UPDATE के बाद ट्रिगर को सक्षम कर सकता हूं:

DISABLE TRIGGER tiu_benefit ON benefit;  
GO  
UPDATE benefit SET editor = 'srh' where benefit_id = 9876
GO
ENABLE TRIGGER tiu_benefit ON benefit;  
GO  

लेकिन यह अक्षम और सक्षम ट्रिगर वर्तमान में लॉग इन सभी उपयोगकर्ताओं को प्रभावित करेगा। इसलिए ऐसी संभावना है कि कोई अन्य उपयोगकर्ता UPDATE / INSERT चलाता है जबकि ट्रिगर मेरी स्क्रिप्ट द्वारा अक्षम है जो अच्छा नहीं है। यही कारण है कि मैं केवल अपने वर्तमान सत्र के लिए ट्रिगर को अक्षम और सक्षम करना चाहता हूं। क्या यह संभव है? यदि हाँ तो कृपया बताएं कि कैसे।

धन्यवाद


1
यदि आप अपने ट्रिगर को संशोधित नहीं कर सकते हैं, तो उत्तर नहीं है।
जिओ

जवाबों:


6

मैंने इस पर कुछ परीक्षण किया और मुझे लगता है कि यदि आप एक ही लेनदेन में अपनी प्रक्रिया चलाते हैं तो आप ठीक होंगे।

BEGIN TRANSACTION
GO

DISABLE TRIGGER tiu_benefit ON benefit;
GO

UPDATE benefit
SET editor = 'srh'
WHERE benefit_id = 9876
GO

ENABLE TRIGGER tiu_benefit ON benefit;
GO

--Decide to commit or rollback

--commit
--rollback 

अपने परीक्षण में, मैंने केवल BEGIN TRANSACTIONऔर सबसे DISABLE TRIGGERपहले पर प्रकाश डाला और निष्पादित किया । मैं तो एक नया (दूसरा) क्वेरी खिड़की खोल दिया और विभिन्न DML बयान (भागने की कोशिश की SELECT, INSERT, UPDATE DELETE) आधार तालिका के खिलाफ। स्पष्ट लेनदेन के साथ खिड़की द्वारा रखे गए ताले पर प्रतीक्षा की गई दूसरी क्वेरी विंडो में बेस टेबल तक पहुंचने के सभी प्रयास। एक बार जब मैंने अपना स्पष्ट लेन-देन किया (या वापस लुढ़का), तो दूसरी विंडो टेबल तक पहुंचने में सक्षम थी।


यह काम करेगा, लेकिन ताले अनजाने समस्याओं को नीचे की ओर ले जा सकते हैं, यह निर्भर करता है कि आप लेन-देन को कितने समय तक खुला रखते हैं।
सीएएम

@CaM - मुझे लगता है कि एक पंक्ति अपडेट में ओपी कमिट्स या लेन-देन को जल्दी वापस लेने में बहुत समय नहीं लगेगा। उम्मीद है कि benefit_id:) पर एक सूचकांक है
स्कॉट होडगिन

वास्तव में इस समाधान को पसंद किया क्योंकि मुझे ट्रिगर में कोई बदलाव नहीं करना है
srh

18

आपकी समस्या को हल करने के लिए, हमें समस्या के लिए एक प्रोग्रामेटिक तरीका अपनाना होगा। यहां जाने के लिए दो मार्ग हैं। इन दृष्टिकोणों की आवश्यकता का कारण यह है कि आप किसी विशेष विवरण के लिए ट्रिगर को अक्षम नहीं कर सकते, यह केवल तालिका की संपूर्णता के लिए अक्षम किया जा सकता है।

विकल्प 1: संदर्भ_इन्फो ()

MS SQL टिप्स पर सैमुअल वंगा का एक बेहतरीन उदाहरण था:

USE AdventureWorks; 
GO 
-- creating the table in AdventureWorks database 
IF OBJECT_ID('dbo.Table1') IS NOT NULL 
DROP TABLE dbo.Table1 
GO 
CREATE TABLE dbo.Table1(ID INT) 
GO 
-- Creating a trigger 
CREATE TRIGGER TR_Test ON dbo.Table1 FOR INSERT,UPDATE,DELETE 
AS 
DECLARE @Cinfo VARBINARY(128) 
SELECT @Cinfo = Context_Info() 
IF @Cinfo = 0x55555 
RETURN 
PRINT 'Trigger Executed' 
-- Actual code goes here 
-- For simplicity, I did not include any code 
GO

अब जब सैमुअल नहीं चाहता कि ट्रिगर को क्रियान्वित किया जाए, तो वे इसका उपयोग करते हैं:

SET Context_Info 0x55555 
INSERT dbo.Table1 VALUES(100)

Context_Info वर्तमान सत्र के बारे में जानकारी प्राप्त करने के लिए निम्नलिखित सिस्टम दृश्यों का उपयोग करता है:

  • sys.dm_exec_requests

  • sys.dm_exec_sessions

  • sys.sysprocesses

यहां विचारधारा यह है कि आप जो बाइनरी स्ट्रिंग सेट कर रहे हैं, वह केवल वर्तमान सत्र के लिए ही सामने आती है, इसलिए जब ट्रिगर आपके सत्र के दौरान निष्पादित होता है, तो यह Context_infoफ़ंक्शन के स्कोप और चर सेटिंग को देखेगा और यह ट्रिगर के भागने वाले हिस्से पर कूद जाएगा बजाय।

विकल्प 2: अस्थायी तालिका

इत्ज़िक बेन-गण की अपनी पुस्तक "इनसाइड माइक्रोसॉफ्ट SQL सर्वर 2008 टी-एसक्यूएल प्रोग्रामिंग: टी-एसक्यूएल प्रोग्रामिंग" में एक महान समाधान है जो उनकी बाद की पुस्तक टी-एसक्यूएल क्वेरी में भी है । इस context_infoसमारोह के साथ प्राथमिक समस्या मामूली TempDB ओवरहेड है।

आश्चर्य को खराब करने के लिए लेकिन किताबों की साजिश को बर्बाद न करें (मुझे लगा कि वे खरीदने और पढ़ने के लायक हैं), आप अपने ट्रिगर को बदल देंगे।

आपके ट्रिगर को एक अस्थायी तालिका के लिए एक चेक प्रदर्शन करना चाहिए। यदि अस्थायी तालिका मौजूद है, तो ट्रिगर को समाप्त होने और क्रियाओं को करने के लिए पता होना चाहिए।

अपडेट स्टेटमेंट में आप जो प्रदर्शन करना चाहते हैं, पहले अस्थायी तालिका बनाएं। यह ट्रिगर के समान लेनदेन में देखा जाएगा और यह ट्रिगर को आपके कथन की अनदेखी करेगा।

ट्रिगर का उदाहरण:

CREATE TRIGGER TRIGGERNAME ON TABLENAME for INSERT AS

IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
GO

जब आप ट्रिगर को चलाना नहीं चाहते हैं, तो प्रारंभिक कथन का उदाहरण:

CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);

अपने उदाहरण के लिए इसे पूरी तरह से रखना:

ALTER TRIGGER tiu_benefit ON benefit FOR 
... 
AS
...
IF OBJECT_ID('tempdb..#FAKETEMPTABLE') IS NOT NULL RETURN;
--... rest of code here
GO

CREATE TABLE #FAKETEMPTABLE(col1 SMALLINT);
UPDATE benefit SET editor = 'srh' where benefit_id = 9876;
GO

2
मैं ट्रिगर में अस्थायी तालिका के बजाय संदर्भ_info () का उपयोग करेगा। दूसरे शब्द में, यदि ट्रिगर से तात्पर्य है संदर्भ_info एक विशिष्ट मूल्य देता है, तो ट्रिगर तदनुसार कार्य करेगा। आप प्रासंगिक एसओ प्रश्न का उल्लेख यहां कर सकते हैं: stackoverflow.com/questions/3025662/…
jyao

1
यदि आप किसी विशिष्ट व्यक्ति को ट्रिगर मार रहे हैं तो ट्रिगर को कभी नहीं चलाने के लिए context_infoउपयोग original_login()करने के लिए आप एक समान चेक में डाल सकते हैं ।
केनेथ फिशर

2

मैं CONTEXT_INFOया तो नया प्रयोग करूंगा SESSION_CONTEXT। दोनों सत्र आधारित मूल्य हैं।

  • CONTEXT_INFOएक एकल VARBINARY(128)मूल्य है। यह कम से कम SQL Server 2000 के बाद से उपलब्ध है। CONTEXT_INFOकिसी के भी देखने योग्य है VIEW SERVER STATEक्योंकि यह sys.dm_exec_sessionsDMV द्वारा लौटाया गया फ़ील्ड है । मैंने पहले भी इसका इस्तेमाल किया है और यह काफी अच्छा काम करता है।

    सेट के माध्यम से सेट करें CONTEXT_INFO के
    माध्यम से प्राप्त करें CONTEXT_INFO () या sysinos_exec_session

    आपके द्वारा संग्रहित किए जाने वाले मूल्य के प्रकार पर निर्भर करते हुए CONTEXT_INFO, कुछ बारीकियों के बारे में पता होना चाहिए। मुझे लगता है कि निम्नलिखित ब्लॉग पोस्ट में कवर:

    क्यों नहीं CONTEXT_INFO () SET CONTEXT_INFO द्वारा निर्धारित सटीक मान लौटाएं?

  • Session_context SQL_VARIANTमूल्यों का एक महत्वपूर्ण / मूल्य युग्म है । इसे SQL सर्वर 2016 में पेश किया गया था। विभिन्न उद्देश्यों के लिए मूल्यों का पृथक्करण काफी अच्छा है। Session_context केवल वर्तमान सत्र द्वारा देखा जा सकता है।

    इस मान को sp_set_session_context के माध्यम से सेट करें
    । इस मान को SESSION_CONTEXT के माध्यम से प्राप्त करें

स्थानीय अस्थायी तालिका विकल्प और यहां तक ​​कि अक्षम / सक्षम ट्रिगर विकल्प के बारे में विचार करने के लिए एक चीज: दोनों को कुछ मात्रा में लॉकिंग और ट्रांस लॉग गतिविधि की आवश्यकता होती है। उन दोनों विकल्पों में विवाद की संभावना बढ़ जाती है, भले ही न्यूनतम रूप से। दो "संदर्भ" विकल्प हल्के वजन / स्मृति-मात्र होना चाहिए।


reference_info एक दर्द निवारक है, जब भी आप उत्पादन डेटा परिवर्तन चलाना चाहते हैं तो यह काम में आता है, विशेष रूप से ट्रिगर को अक्षम करने से अन्य ऑपरेशन ट्रिगर नहीं हो सकते हैं।
बीजू जोस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.