2012-04-09 12 views
10

एमएस एसक्यूएल सर्वर 2008 आर 2 में, हम एक प्री-डालने और प्री-अपडेट ट्रिगर चाहते हैं जो कुछ जांचता है और रोलबैक (raiserror के माध्यम से) चल रहा है/अपडेट करता है।ट्रिगर से रोलबैक लेनदेन

प्रश्न: INSTEAD OF ट्रिगर में। क्या किसी को वास्तव में डालने या अपडेट को स्पष्ट रूप से लिखना है? क्योंकि हम डिफ़ॉल्ट डालने या अपडेट करना चाहते हैं और केवल "प्रीचेक" करते हैं।

+0

"Precheck" की प्रकृति क्या है? ट्रिगर्स के पास 'डाली गई'/'हटाई गई' तालिकाओं का प्रबंधन करने के लिए एक ओवरहेड होता है। क्या यह ऐसा कुछ है जिसे किसी अन्य तरीके से लागू किया जा सकता है? –

+0

हमें केवल एक कॉलम में रिक्त तारों को अनदेखा करने वाले ट्रिपल (3 कॉलम) पर एक अनूठी बाधा है। – Cartesius00

+0

तो tuple '(a, b, c) 'के लिए' ''' के पास खाली स्ट्रिंग का मान है, तो आप अद्वितीय बाधा के उद्देश्यों के लिए उस ट्यूपल को पूरी तरह से अनदेखा करना चाहते हैं? –

उत्तर

9

हां।

आपको स्पष्ट INSERT या UPDATE लिखने की आवश्यकता है।

ट्रिगर INSTEAD OF डीएमएल ऑपरेशन चलाता है। यदि आप ट्रिगर को रिक्त छोड़ देते हैं तो INSERTED/DELETED टेबलों के अलावा कोई भी क्रिया नहीं होगी और tempdb में पॉप्युलेट किया जाएगा।

हालांकि टिप्पणियों में चर्चा से मैं इसके लिए एक ट्रिगर का उपयोग नहीं करता लेकिन एक अद्वितीय फ़िल्टर किए गए इंडेक्स CREATE UNIQUE INDEX ix ON T(a,b,c) WHERE c <> '' का उपयोग करता हूं। यह अधिक प्रदर्शन करने की संभावना है और समेकन से निपटने के दौरान संभावित तर्क मुद्दों से बचने की संभावना है।

+0

धन्यवाद। और उन डीएमएल परिचालनों में डाली गई और अद्यतन पंक्तियों के लिए उपनाम क्या हैं? – Cartesius00

+0

@ जेम्स - 'निहित' और 'हटा दिया गया' लेकिन ये सारणी पंक्तियां नहीं हैं। ट्रिगर प्रति बयान एक बार आग लगती है। तो 'आपके द्वारा चुने गए चयन * में शामिल' एक सामान्य 'इन्टरनेट' इन्टरनेट ट्रिगर होगा। –

+0

और क्या होगा यदि 'YourTable' में पहचान कॉलम और कई अन्य कॉलम हों। 'चुनें *' एक समस्या है, है ना? – Cartesius00

3

शायद आप INSTEAD OF ट्रिगर नहीं चाहते हैं जब तक कि आप वास्तविक डालने या अपडेट को प्रतिस्थापित नहीं करना चाहते हैं। आपके मामले में, आप इसके बजाय FOR INSERT, UPDATE ट्रिगर चाहते हैं।

यह उदाहरण ट्रिगर क्लाइंट को एक संदेश प्रिंट करता है जब कोई शीर्षक तालिका में डेटा जोड़ने या बदलने का प्रयास करता है।

USE pubs 
IF EXISTS (SELECT name FROM sysobjects 
     WHERE name = 'reminder' AND type = 'TR') 
    DROP TRIGGER reminder 
GO 
CREATE TRIGGER reminder 
ON titles 
FOR INSERT, UPDATE 
AS RAISERROR ('inserts and updates to the titles table is not allowed', 16, 1) 
GO 

तुम भी IF EXISTS या COLUMNS_UPDATED रूप में अच्छी तरह तरह बातें इस्तेमाल कर सकते हैं।

रोलबैक का उपयोग करने वाला एक और उदाहरण यहां।

USE pubs 
IF EXISTS (SELECT name FROM sysobjects 
     WHERE name = 'employee_insupd' AND type = 'TR') 
    DROP TRIGGER employee_insupd 
GO 
CREATE TRIGGER employee_insupd 
ON employee 
FOR INSERT, UPDATE 
AS 
/* Get the range of level for this job type from the jobs table. */ 
DECLARE @min_lvl tinyint, 
    @max_lvl tinyint, 
    @emp_lvl tinyint, 
    @job_id smallint 
SELECT @min_lvl = min_lvl, 
    @max_lvl = max_lvl, 
    @emp_lvl = i.job_lvl, 
    @job_id = i.job_id 
FROM employee e INNER JOIN inserted i ON e.emp_id = i.emp_id 
    JOIN jobs j ON j.job_id = i.job_id 
IF (@job_id = 1) and (@emp_lvl <> 10) 
BEGIN 
    RAISERROR ('Job id 1 expects the default level of 10.', 16, 1) 
    ROLLBACK TRANSACTION 
END 
ELSE 
IF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl) 
BEGIN 
    RAISERROR ('The level for job_id:%d should be between %d and %d.', 
     16, 1, @job_id, @min_lvl, @max_lvl) 
    ROLLBACK TRANSACTION 
END 

मैं अगर आप किसी लेन-देन नहीं है या यकीन नहीं है, लेकिन आपके मामले में आप निम्नलिखित की तरह कुछ चाहेगा:

USE myDatabase 

    IF EXISTS (SELECT name FROM sysobjects 
      WHERE name = 'myTable' AND type = 'TR') 
     DROP TRIGGER tr_myTrigger 
    GO 
    CREATE TRIGGER tr_myTrigger 
    ON myTable 
    FOR INSERT, UPDATE 
    AS 

if(exists(select * from inserted where rtrim(c) <> '')) 
begin 
    -- check to make sure the insert(s) are unique 

    if(exists(
     select * from inserted i 
     join dbo.myTable t on i.a = t.a and i.b = t.b and i.c = t.c) 

    begin 
     raiserror('Duplicate(s) found', 16, 1) 
     rollback transaction 
    end 
end 
संबंधित मुद्दे