2009-04-15 13 views
6

की संख्या अद्यतन करने के लिए इस समझने में अधिक आसान बनाने के लिए, मैं ठीक उसी समस्या पेश करेंगे जैसे कि यह (वास्तविक एप्लिकेशन पर मंचों से कोई लेना देना नहीं है एक मंच के बारे में था सब, लेकिन मुझे लगता है कि हम में से अधिकांश को समझना आसान है, वास्तविक ऐप कुछ विशिष्ट है कि अधिकांश प्रोग्रामर समझ नहीं पाएंगे (यह कट्टर ग्राफिक डिजाइनरों के लिए एक ऐप है))।एमएस एसक्यूएल सर्वर ट्रिगर आइटम रेटिंग और वोट

मान लीजिए कि एक थ्रेड टेबल है जो प्रत्येक फोरम थ्रेड और थ्रेड्रेटिंग टेबल के बारे में जानकारी संग्रहीत करती है जो प्रति उपयोगकर्ता थ्रेड रेटिंग (1-5) स्टोर करती है। दक्षता के लिए मैंने थ्रेड टेबल में रेटिंग औसत और वोटों की संख्या को कैश करने का निर्णय लिया और इसे अपडेट करने के लिए एक अच्छा विचार की तरह ट्रिगर्स (मैं वास्तविक एप्लिकेशन कोड में ऐसी चीजें करता था, लेकिन मुझे लगता है कि ट्रिगर एक कोशिश के लायक हैं, बावजूद डिबगिंग खतरे)।

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

CREATE TRIGGER thread_rating ON threadrating 
AFTER INSERT 
AS 
    UPDATE thread 
    SET 
     thread.rating = (thread.rating * thread.voters + SUM(inserted.rating))/(thread.voters + COUNT(inserted.rating)), 
     thread.voters = thread.voters + COUNT(inserted.rating) 
    FROM thread 
    INNER JOIN inserted ON(inserted.threadid = thread.threadid) 
    GROUP BY inserted.threadid 

लेकिन मैं "द्वारा समूह" खंड के लिए कोई त्रुटि मिलती है (जो मैं उम्मीद)। सवाल यह है कि, मैं यह काम कैसे कर सकता हूं?

क्षमा सवाल बेवकूफ है, लेकिन यह पहली बार मैं वास्तव में चलाता उपयोग करने का प्रयास हो चुका है।

अतिरिक्त जानकारी: थ्रेड तालिका में थ्रेडिड (int, प्राथमिक कुंजी), रेटिंग (फ्लोट), मतदाता (int) और कुछ अन्य फ़ील्ड होंगे जो वर्तमान प्रश्न के लिए अपरिवर्तनीय हैं। थ्रेड्रेटिंग तालिका में केवल थ्रेडिड (विदेशी कुंजी), उपयोगकर्ता आईडी (उपयोगकर्ता तालिका की प्राथमिक कुंजी के लिए विदेशी कुंजी) और रेटिंग (1 और 5 के बीच टिनिंट) शामिल है।

त्रुटि संदेश "कीवर्ड 'ग्रुप' के पास गलत वाक्य रचना है।"

+0

मेज पर प्राथमिक कुंजी क्या है

यहाँ अपने समस्या का समाधान है? –

+0

तालिका पोस्ट करना डीएमएल और वास्तविक त्रुटि संदेश भी मदद करेगा। –

उत्तर

2

पहले, मैं सुझाव है कि आप नहीं उपयोग चलाता।

यदि आपको वाक्यविन्यास त्रुटि मिल रही है, तो जांचें कि आपके माता-पिता संतुलित हैं और साथ ही आपके begin/ends हैं। आपके मामले में, आपके पास end (अंत में) है लेकिन कोई शुरुआत नहीं है। आप इसे ठीक कर सकते हैं end को हटा दें।

एक बार जब आप ठीक, आप की संभावना कुछ और त्रुटियों की तरह "कॉलम एक्स, वाई, जेड एक समग्र या द्वारा समूह में नहीं" मिल जाएगा। ऐसा इसलिए है क्योंकि आपके पास कई कॉलम हैं जो दोनों में नहीं हैं। आपको अपने समूह में thread.rating, thread.voters इत्यादि जोड़ना होगा या उन पर कुछ प्रकार का योग करना होगा।

यह सब मानते हुए वहाँ एक ही threadid (यानी, यह प्राथमिक कुंजी नहीं है) के साथ कई रिकॉर्ड हैं कि है। यदि यह मामला नहीं है, तो समूह का उद्देश्य क्या है?


संपादित करें:

मैं सिंटेक्स त्रुटि पर स्टम्प्ड रहा हूँ। मैंने इसके साथ दो सहसंबंधित उप प्रश्नों के साथ काम किया।मैं अपनी मेज संरचना पर अनुमान लगाया रूप में की जरूरत है ताकि संशोधित करने और इस प्रयास करें:

--CREATE TABLE ThreadRating (threadid int not null, userid int not null, rating int not null) 
--CREATE TABLE Thread (threadid int not null, rating int not null, voters int not null) 

ALTER TRIGGER thread_rating ON threadrating 
AFTER INSERT 
AS 

UPDATE Thread 
SET Thread.rating = 
    (SELECT (Thread.Rating * Thread.Voters + SUM(I.Rating))/(Thread.Voters + COUNT(I.Rating)) 
    FROM ThreadRating I WHERE I.ThreadID = thread.ThreadID) 
    ,Thread.Voters = 
    (SELECT Thread.Voters + COUNT(I.Rating) 
    FROM ThreadRating I WHERE I.ThreadID = Thread.ThreadID)       
FROM Thread 
JOIN Inserted ON Inserted.ThreadID = Thread.ThreadID 

हैं जैसे आप चाहते हैं कि, तो हम प्रदर्शन/कार्य योजना लागू की जाँच करें और आवश्यकतानुसार संशोधित कर सकते हैं। हम अभी तक समूह के साथ काम करने में सक्षम हो सकते हैं।


विकल्प को ट्रिगर करने

आप डेटा है कि केवल कुछ गिने-चुने स्थानों में प्रभाव मूल्यांकन, मैं सीधे वहाँ रेटिंग को अद्यतन करने की सलाह देते हैं अपडेट कर रहे हैं। एक ट्रिगर में तर्क फैक्टरिंग अच्छा है लेकिन बहुत सारी समस्याएं प्रदान करता है (प्रदर्शन, दृश्यता, आदि)। यह एक समारोह द्वारा सहायता प्राप्त की जा सकती है।

इस पर विचार करें: आपका ट्रिगर उस तालिका को छूने पर हर बार निष्पादित करेगा। दृश्य गणना, अंतिम अद्यतन दिनांक इत्यादि जैसी चीजें इस ट्रिगर को निष्पादित करेंगी। आप उन मामलों में ट्रिगर शॉर्ट सर्किट में तर्क जोड़ सकते हैं लेकिन यह तेजी से जटिल हो जाता है।

+0

थ्रेड्रेटिंग टेबल में एक ही थ्रेडिड के साथ कई पंक्तियां हो सकती हैं, थ्रेड टेबल में नहीं। मुझे आपके द्वारा उल्लिखित एक ही त्रुटि की उम्मीद है, लेकिन मुझे अधिक अपमानजनक "कीवर्ड 'ग्रुप' के पास गलत वाक्यविन्यास मिल रहा है। यदि आप डॉन करते हैं ट्रिगर्स की अनुशंसा नहीं करते हैं, आप इस तरह के मामले के लिए क्या सलाह देंगे? –

+0

अंत में "एंड" कीवर्ड हटाएं। (या 'as' के बाद 'start' शब्द जोड़ें) –

+0

मैंने पहले संपादन नहीं देखा है। नहीं, थ्रेड्रेटिंग टेबल में केवल 3 फ़ील्ड हैं: थ्रेडिड, यूजरिड, रेटिंग। क्या आप प्रदर्शन भाग पर विस्तार कर सकते हैं? मैंने उस पूरी अवधारणा को पी के लिए तय किया विकृति के कारण ... –

1

आप निम्न पढ़ने से सहायक हो सकता:

An introduction to Triggers
Wikipedia: DB Triggers

+0

मैं कम से कम पिछले 3 घंटों के लिए उन्हें करने के लिए ट्रिगर्स और एसक्यूएल सर्वर के तरीके के बारे में पढ़ रहा हूं ... कुछ भी मेरे विशेष मामले में मदद नहीं करता है :( –

+0

वाह, वह बेकार है! मुझे लगता है कि मुझे कुछ बेहतर लिंक मिल सकते हैं। – Kredns

2

डी ओह! मैंने आपके प्रश्न को पूरी तरह गलत तरीके से पढ़ा और मैंने सोचा कि आप MySQL के बारे में पूछ रहे थे। मी culpa! मैं नीचे दिए गए समाधान को बरकरार रखूंगा, और इसे समुदाय विकी के रूप में चिह्नित करूंगा। शायद यह MySQL पर एक समान समस्या वाले किसी के लिए उपयोगी होगा।


MySQL से चलाता है प्रति पंक्ति क्रियान्वित कर रहे हैं। इसके अलावा छद्म-तालिका "inserted" एक Microsoft SQL सर्वर सम्मेलन है।

MySQL trigger language के एक्सटेंशन के रूप में छद्म-टेबल NEW और OLD का उपयोग करता है।

CREATE TRIGGER thread_rating 
    AFTER INSERT ON threadrating 
    FOR EACH ROW 
BEGIN 
    UPDATE thread 
    SET rating = (rating*voters + NEW.rating)/(voters+1), 
     voters = voters + 1 
    WHERE threadid = NEW.threadid; 
END 

इसी तरह आप UPDATE और DELETE के लिए ट्रिगर आवश्यकता होगी::

CREATE TRIGGER thread_rating 
    AFTER UPDATE ON threadrating 
    FOR EACH ROW 
BEGIN 
    UPDATE thread 
    SET rating = (rating*voters - OLD.rating + NEW.rating)/voters, 
    WHERE threadid = NEW.threadid; 
END 

CREATE TRIGGER thread_rating 
    AFTER DELETE ON threadrating 
    FOR EACH ROW 
BEGIN 
    UPDATE thread 
    SET rating = (rating*voters - OLD.rating)/(voters-1), 
     voters = voters - 1 
    WHERE threadid = OLD.threadid; 
END 
+0

लेकिन मैं एमएस एसक्यूएल सर्वर का उपयोग कर रहा हूँ! MySQL के साथ सबकुछ आसान होगा, लेकिन मेरे पास इस प्रोजेक्ट के लिए कोई विकल्प नहीं है :( –

+0

डी ओह! मेरी गलती। शीर्ष पर संपादित करें। –

+0

एनपी, यह निश्चित रूप से दूसरों के लिए उपयोगी साबित होगा :) –

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