2010-08-26 15 views
12

मेरे पास 2 टेबल हैं: comments और comments_likesएक ट्रिगर (बिना ट्रिगर को अक्षम करने के लिए) के बिना mysql में एक क्वेरी बनाएं


टिप्पणी

id  
message 
likes 

चलाता है:

के बाद उसे हटा

DELETE FROM comments_likes WHERE comment_id = OLD.id; 

comments_likes

id   
comment_id 

चलाता है:

के बाद सम्मिलित करें

UPDATE comments SET likes = likes + 1 WHERE comments.id = NEW.comment_id; 

के बाद उसे हटा

UPDATE comments SET likes = likes - 1 WHERE comments.id = OLD.comment_id; 

अद्यतन

**omited code, updates comments** 

तो सवाल यह है के बाद, मैं जब उन्हें एक ट्रिगर से सक्रिय चलाता निष्क्रिय कर सकते हैं?

क्या मैं चाहता हूँ कुछ करना है यह पसंद है:

के बाद उसे हटा

IF NOT called_from_another_trigger() THEN 
    UPDATE comments SET likes = likes - 1 WHERE comments.id = OLD.comment_id; 
END IF; 

[संपादित करें]

एक गैर अनुकूलित समाधान (बहुत धीमी गति से क्वेरी होगा ... प्रत्येक LIKE रजिस्टर के लिए एक क्वेरी बनाता है):

BEGIN 
    IF (SELECT id FROM comments WHERE comments.id = OLD.comment_id) THEN 
     UPDATE comments SET comments.cache_likes = comments.cache_likes - 1 WHERE comments.id = OLD.comment_id; 
    END IF; 
END 

अद्यतन LOW PRIORITY और IGNORE काम नहीं करता है।

[संपादित करें 2]

मैं एक विचार है, पहले ट्रिगर में एक वैश्विक चर सेट और अन्य ट्रिगर से इसे पढ़ने के लिए संभव है?

पूर्व:

पहले ट्रिगर:

@disable_triggers = true; 
// do the stuff that calls another triggers 
@disable_triggers = false; 

अन्य ट्रिगर:

if @disable_triggers = false then 
    // do the stuff 
end if; 

उत्तर

21

अक्षम करने के लिए चलाता है आप कर सकते हैं:

उत्प्रेरक 1

SET @disable_trigger = 1; 
// do stuff that calls trigger 2 
SET @disable_trigger = NULL; 

उत्प्रेरक 2

IF @disable_trigger IS NULL THEN 
    // do stuff only if called from a query and not from trigger 1 
END IF; 
+0

इंजेस्टिंग! क्या आप वास्तव में ट्रिगर के अंदर ट्रिगर्स को अक्षम कर सकते हैं? – Mchl

+1

@Mchl: हाँ, इस विधि के साथ आप कर सकते हैं :) @var कनेक्शन के लिए globals हैं। आपको IS NULL का उपयोग करना चाहिए क्योंकि वेरिएबल्स जिन्हें परिभाषित नहीं किया गया है वे हमेशा शून्य होते हैं। – Wiliam

+1

इससे मुझे 4 साल बाद मदद मिली! मैं बिल्कुल इस तरह कुछ ढूंढ रहा था। Googling के 1 घंटे के बाद और एसओ खोज, मैं अंत में आपका जवाब मिला। यह इतना आसान है, लेकिन मैंने कभी इसे अपने आप से नहीं समझा होगा। मैं सिर्फ mysql के साथ "प्रोग्राम" करने में सक्षम होने के लिए उपयोग नहीं किया जाता है। –

0

नहीं, तुम नहीं कर सकते। यह ट्रिगर्स का मुद्दा है: हमेशा चलने के लिए।

इसके अलावा, मैं नहीं देख सकता कि आपको अपने मामले में इसकी आवश्यकता क्यों होगी। सबसे खराब कुछ भी अपडेट नहीं हो जाता है - कोई त्रुटि नहीं उठाई जाएगी।

आप अपने ट्रिगर में हमेशा एक शर्त जोड़ सकते हैं, यह जांचने के लिए कि क्या वे (या उनके कोड का हिस्सा) चलाना चाहिए (उदाहरण के लिए यदि प्रासंगिक तालिका में कोई रिकॉर्ड है)।

+0

जब आप कोई टिप्पणी हटाने का प्रयास करते हैं, तो ट्रिगर सभी पसंदों को हटा देता है। जब पसंद हटा दी जाती है, तो वे हटाई गई टिप्पणी को अपडेट करते हैं। एक त्रुटि संदेश प्रकट होता है: 'संग्रहित फ़ंक्शन/ट्रिगर में तालिका' टिप्पणियां 'अपडेट नहीं किया जा सकता है क्योंकि यह पहले से ही कथन द्वारा उपयोग किया जाता है जो इस संग्रहीत फ़ंक्शन/ट्रिगर' – Wiliam

+0

@Wiliam को आमंत्रित करता है: ठीक है, एक शर्त के साथ मैं इसे कर सकता हूं ... लेकिन वह समाधान नहीं है जिसे मैं यूयू – Wiliam

+0

@Mchl खोज रहा था शायद यह ट्रिगर्स का बिंदु है, लेकिन MySQL में उन्हें हमेशा निष्पादित नहीं किया जाता है। यदि CASCADE विदेशी कुंजी बाधा प्रवर्तन के कारण कोई पंक्ति हटा दी जाती है, तो कोई ट्रिगर निष्पादित नहीं किया जाता है। संदर्भ: [MySQL दस्तावेज़] (http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html)। मुझे दृढ़ विश्वास है कि MySQL की इस सीमा की जड़ें विलियम की टिप्पणी में त्रुटि के समान मूल कारण हैं। –

1

थोड़ा बदसूरत हो सकता है, लेकिन मुझे क्या नाम बदलने है तालिका 2 में तालिका जो ट्रिगर भी संलग्न नहीं करता है, और फिर, अंत में, पीछे नाम बदलें।

संबंधित मुद्दे