2012-03-12 21 views
5

मैं चलाता और बाधाओं पढ़ रहा हूँ के लिए ट्रिगर का उपयोग।एसक्यूएल बाधा

और मैं एक सवाल ट्रिगर का उपयोग करने के मिल गया (ईमानदारी से कहूं तो मैं सच में कैसे ट्रिगर का उपयोग सुनिश्चित नहीं कर रहा हूँ ..)

मान लीजिए कि हम एक शिक्षक की मेज करते हैं।

और यह शिक्षक तालिका

उदाहरण के लिए

,

|teacher_id|ssn | first_name | last_name | student_number| max_student 
|1   |1234 | bob  | Smith  | 25   |25 
|2   |1235 | kim  | Johnson | 24   |21 
|3   |1236 | kally  | Jones  | 23   |22 

और

चलो कहते हैं कि छात्र संख्या की अधिकतम संख्या 25 हो जाएगा जाने teacher_id, एसएसएन, FIRST_NAME, LAST_NAME, class_time शामिल (छात्र की अधिकतम संख्या शिक्षक द्वारा परिभाषित किया जाएगा, तो यह 10 की तरह किसी भी संख्या, 22, 25 ...)

हो सकता है और एक छात्र बॉब के clas जोड़ना चाहता है रों। हालांकि, मैं उस ट्रिगर को बनाना चाहता हूं जो छात्र को जोड़ने से इनकार कर दे। (क्योंकि बॉब की कक्षा पहले से ही भर चुकी है ..)

हालांकि, मुझे वास्तव में ट्रिगर बनाने का तरीका निश्चित नहीं है .. :(.. (यह ट्रिगर के बारे में अध्ययन करने के लिए ....)

ट्रिगर हिस्सा समझने के लिए नमूना कोड बना सकते हैं किसी को भी मदद के लिए?

+2

आपको उस डेटाबेस को जोड़ना होगा जिसमें आप रुचि रखते हैं, क्योंकि ट्रिगर्स डेटाबेस विशिष्ट होते हैं। –

+0

स्टैक ओवरव्लो में आपका स्वागत है: यदि आप कोड, एक्सएमएल या डेटा नमूने पोस्ट करते हैं, ** कृपया ** टेक्स्ट एडिटर में उन पंक्तियों को हाइलाइट करें और संपादक टूलबार पर "कोड नमूने" बटन ('{}') पर क्लिक करें, अच्छी तरह से प्रारूपित करें और वाक्यविन्यास इसे हाइलाइट करें! गन्दा ' ' ऑर्गेज और '
'टैग, वास्तव में .... –

+1

यह एक व्यवसाय नियम है, जिसे मैं डेटाबेस में ट्रिगर या बाधा के बजाए आपके एप्लिकेशन सॉफ़्टवेयर में लागू होने की उम्मीद करता। डाटाबेस बाधाएं और ट्रिगर्स आम तौर पर रेफरेंशियल अखंडता को लागू करते हैं (यानी, वे आंतरिक रूप से डेटा को लगातार रखते हैं) और हालांकि यह संभवतः बैकस्टॉप हो सकता है ताकि यह सुनिश्चित किया जा सके कि कक्षाएं 25 से अधिक न हों, तो आपके ऐप को वास्तव में पहले स्थान पर प्रयास करना बंद कर देना चाहिए। –

उत्तर

10

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

दूसरा, मुझे लगता है कि एक AFTER ट्रिगर उपयुक्त है (बल्कि एक INSTEAD OF ट्रिगर से)।

तीसरा, इस विदेशी कुंजी और और पंक्ति-स्तर CHECK की कमी का उपयोग कर लागू किया जा सकता।

एक अवरोध प्रकार ट्रिगर के लिए, विचार आम तौर पर ट्रिगर की परीक्षा में तो बुरा डेटा लौटाने के लिए कि इस परिणाम खाली है एक प्रश्न लिखने के लिए है।

आप अपने टेबल के बहुत सी जानकारियां पोस्ट नहीं किया है तो मुझे लगता है कि होगा। मुझे लगता है कि student_number छात्रों का एक तालमेल होना है; यह है के रूप में यह एक पहचानकर्ता की तरह लगता है तो मैं नाम बदल सकते हैं और छात्रों के लिए पहचानकर्ता समझेंगे student_id है:

CREATE TRIGGER student_tally_too_high ON Enrolment 
AFTER INSERT, UPDATE 
AS 
IF EXISTS (
      SELECT * 
      FROM Teachers AS T 
        INNER JOIN (
           SELECT teacher_id, COUNT(*) AS students_tally 
           FROM Enrolment 
           GROUP 
            BY teacher_id  
          ) AS E 
            ON T.teacher_id = E.teacher_id 
            AND E.students_tally > T.students_tally 
     ) 
BEGIN 
RAISERROR ('A teachers''s student tally is too high to accept new students.', 16, 1); 
ROLLBACK TRANSACTION; 
RETURN 
END; 

:

WITH EnrolmentTallies 
    AS 
    (
     SELECT teacher_id, COUNT(*) AS students_tally 
     FROM Enrolment 
     GROUP 
      BY teacher_id  
    ) 
SELECT * 
    FROM Teachers AS T 
     INNER JOIN EnrolmentTallies AS E 
     ON T.teacher_id = E.teacher_id 
      AND E.students_tally > T.students_tally; 

एसक्यूएल सर्वर में, ट्रिगर परिभाषा कुछ इस तरह दिखेगा हालांकि, कुछ और विचार हैं। तालिका के लिए हर UPDATE के बाद इस तरह के एक प्रश्न निष्पादित बहुत अक्षम हो सकता है। आप UPDATE() का उपयोग (या COLUMNS_UPDATED अगर आपको लगता है स्तंभ आदेश पर भरोसा किया जा सकता है) और/या deleted और inserted वैचारिक टेबल क्वेरी के दायरे को सीमित करने और जब यह आग है चाहिए। आपको यह सुनिश्चित करने की भी आवश्यकता होगी कि समेकन समस्याओं को रोकने के लिए लेन-देन सही ढंग से क्रमबद्ध किया गया हो। हालांकि शामिल है, यह बहुत जटिल नहीं है।

मैं अत्यधिक पुस्तक Applied Mathematics for Database Professionals  By Lex de Haan, Toon Koppelaars, अध्याय 11 (कोड उदाहरण ओरेकल हैं, लेकिन आसानी से एसक्यूएल सर्वर पर वापस पोर्ट जा सकता है) की सलाह देते हैं।


यह ट्रिगर्स के बिना एक ही प्राप्त करने के लिए संभव हो सकता है। विचार नामांकन में संदर्भित करने के लिए (teacher_id, students_tally) पर एक सुपरकी बनाना है, जिसके लिए अद्वितीय छात्र घटनाओं का अनुक्रम एक परीक्षण के साथ बनाए रखा जाएगा कि अनुक्रम अधिकतम मिलान से अधिक कभी नहीं होगा।

CREATE TABLE Students 
(
student_id INTEGER NOT NULL, 
UNIQUE (student_id) 
); 

CREATE TABLE Teachers 
(
teacher_id INTEGER NOT NULL, 
students_tally INTEGER NOT NULL CHECK (students_tally > 0), 
UNIQUE (teacher_id), 
UNIQUE (teacher_id, students_tally) 
); 

CREATE TABLE Enrolment 
(
teacher_id INTEGER NOT NULL UNIQUE, 
students_tally INTEGER NOT NULL CHECK (students_tally > 0), 
FOREIGN KEY (teacher_id, students_tally) 
    REFERENCES Teachers (teacher_id, students_tally) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
student_id INTEGER NOT NULL UNIQUE 
    REFERENCES Students (student_id), 
student_teacher_sequence INTEGER NOT NULL 
    CHECK (student_teacher_sequence BETWEEN 1 AND students_tally) 
UNIQUE (teacher_id, student_id), 
UNIQUE (teacher_id, student_id, student_teacher_sequence) 
); 

फिर कुछ 'सहायता' पर संग्रहीत procs/कार्य अद्यतन पर अनुक्रम बनाए रखने के लिए जोड़ें:

यहाँ कुछ नंगे हड्डियों एसक्यूएल DDL है।

+0

क्षमा करें, मैं तालिका से max_student रखना भूल जाते हैं। मैं ट्रिगर बनाने के लिए अध्ययन कर रहा हूं जो छात्र नामांकन की सीमा निर्धारित करने में सक्षम है जब छात्र कक्षाओं में दाखिला लेना चाहता हूं। उदाहरण के लिए, यदि max_student == student_number तो छात्र कक्षा नहीं जोड़ सकता है। वैसे भी, यह वास्तव में मुझे ट्रिगर समझने में मदद करता है। धन्यवाद :) –

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