2008-11-27 22 views
44

में एक चयन संग्रहीत करना मेरे पास एक ट्रिगर है जिसमें मैं एक वैरिएबल रखना चाहता हूं जिसमें एक INT है जो मुझे SELECT से मिलता है, इसलिए मैं SELECT को दो बार कॉल करने के बजाय इसे दो IF कथन में उपयोग कर सकता हूं। आप MySQL ट्रिगर्स में चर का उपयोग/उपयोग कैसे करते हैं?MySQL ट्रिगर - एक चर

उत्तर

6
`CREATE TRIGGER `category_before_ins_tr` BEFORE INSERT ON `category` 
    FOR EACH ROW 
BEGIN 
    **SET @tableId= (SELECT id FROM dummy LIMIT 1);** 

END;`; 
+1

मैंने इसे फ़ॉर्मेटिंग के लिए संपादित किया है, इसलिए आप यह सुनिश्चित करने के लिए जांचना चाहेंगे कि यह अभी भी वाक्य रचनात्मक रूप से सही है। –

1

या फिर आप एसक्यूएल में SELECT कथन है कि ट्रिगर लागू होता है, ताकि इसके ट्रिगर पंक्ति (यों) में स्तंभों में से एक के रूप में में पारित शामिल कर सकते हैं। जब तक आप निश्चित हैं कि यह अविश्वसनीय रूप से केवल एक पंक्ति (इसलिए एक मान) लौटाएगा। (और, ज़ाहिर है, इसे एक मान वापस नहीं करना चाहिए जो ट्रिगर में तर्क के साथ इंटरैक्ट करता है, लेकिन यह किसी भी मामले में सच है।)

40

आप DECLARE वाक्यविन्यास के साथ, MySQL ट्रिगर्स में स्थानीय चर घोषित कर सकते हैं।

यहाँ एक उदाहरण है:

DROP TABLE IF EXISTS foo; 
CREATE TABLE FOO (
    i SERIAL PRIMARY KEY 
); 

DELIMITER // 
DROP TRIGGER IF EXISTS bar // 

CREATE TRIGGER bar AFTER INSERT ON foo 
FOR EACH ROW BEGIN 
    DECLARE x INT; 
    SET x = NEW.i; 
    SET @a = x; -- set user variable outside trigger 
END// 

DELIMITER ; 

SET @a = 0; 

SELECT @a; -- returns 0 

INSERT INTO foo() VALUES(); 

SELECT @a; -- returns 1, the value it got during the trigger 

जब आप एक चर को कोई मान निर्दिष्ट है, तो आप यह सुनिश्चित करना चाहिए कि क्वेरी केवल एक ही मूल्य है, न पंक्तियों का एक सेट या स्तंभों का एक सेट देता है। उदाहरण के लिए, यदि आपकी क्वेरी अभ्यास में एक मूल्य लौटाती है, तो यह ठीक है लेकिन जैसे ही यह एक से अधिक पंक्ति लौटाता है, आपको "ERROR 1242: Subquery returns more than 1 row" मिलता है।

यह सुनिश्चित करने के लिए कि स्थानीय चर एक ही मान पर सेट है, आप LIMIT या MAX() का उपयोग कर सकते हैं।

CREATE TRIGGER bar AFTER INSERT ON foo 
FOR EACH ROW BEGIN 
    DECLARE x INT; 
    SET x = (SELECT age FROM users WHERE name = 'Bill'); 
    -- ERROR 1242 if more than one row with 'Bill' 
END// 

CREATE TRIGGER bar AFTER INSERT ON foo 
FOR EACH ROW BEGIN 
    DECLARE x INT; 
    SET x = (SELECT MAX(age) FROM users WHERE name = 'Bill'); 
    -- OK even when more than one row with 'Bill' 
END// 
+0

क्या एक चर में परिणाम सेट स्टोर करना संभव है, या क्या आपको अलग-अलग प्रश्न जारी करना है? – sunwukung

+0

नहीं, एक चर केवल एक ही मूल्य स्टोर कर सकता है। आपको तालिका के कॉलम की तरह चर के लिए एक SQL डेटा प्रकार घोषित करना होगा।MySQL में कोई डेटा प्रकार नहीं है जो परिणाम सेट संग्रहीत करता है। –

+0

यह शर्म की बात है कि उपयोगकर्ता इस उत्तर को स्वीकार करने के लिए नहीं है, क्योंकि यह सही है। –

5
CREATE TRIGGER clearcamcdr AFTER INSERT ON `asteriskcdrdb`.`cdr` 
FOR EACH ROW 
BEGIN 
    SET @INC = (SELECT sip_inc FROM trunks LIMIT 1); 
    IF NEW.billsec >1 AND NEW.channel LIKE @INC 
    AND NEW.dstchannel NOT LIKE "" 
    THEN 
    insert into `asteriskcdrdb`.`filtre` (id_appel,date_appel,source,destinataire,duree,sens,commentaire,suivi) 
     values (NEW.id,NEW.calldate,NEW.src,NEW.dstchannel,NEW.billsec,"entrant","",""); 
    END IF; 
END$$ 

न कोशिश इस @ घर

0

मैं इस समाधान पोस्टिंग रहा हूँ क्योंकि मैं खोजने मैं क्या जरूरत बहुत मेहनत करनी पड़ी। इस पोस्ट ने मुझे काफी करीब (उस के लिए +1 धन्यवाद), और के लिए अंतिम समाधान है, यदि डेटा परीक्षण से मेल खाता है तो सम्मिलित करने से पहले कॉलम डेटा को पुन: व्यवस्थित करना।

नोट:

  1. अद्वितीय कुंजी rridprefix + rrid
  2. की एक समग्र है इससे पहले कि मैं पदभार संभाल लिया है कोई बाधा अद्वितीय कुंजी
  3. नकल को रोकने नहीं था: यह एक विरासत परियोजना मैं विरासत में मिला है जहां से है
  4. हमें मुख्य तालिका में दो तालिकाओं (डुप्लिकेट से भरा) जोड़ना होगा, जो अब समग्र कुंजी पर बाधा डालती है (इसलिए विलय विफल हो जाता है क्योंकि प्राप्त करने वाली तालिका डुप्लीकेट को अशुद्ध तालिका से अनुमति नहीं देगी)
  5. on duplicate key आदर्श से कम है क्योंकि कॉलम भी कई हैं और

वैसे भी बदल सकता है, यहाँ ट्रिगर है कि एक विरासत स्तंभ में किसी भी डुप्लिकेट चाबी डालता है, जबकि हमें विरासत स्टोर करने के लिए अनुमति देता है, बुरा डेटा (है और प्राप्त करने वाली टेबल समग्र, अद्वितीय कुंजी ट्रिगर नहीं करें)

BEGIN 
    -- prevent duplicate composite keys when merging in archive to main 
    SET @EXIST_COMPOSITE_KEY = (SELECT count(*) FROM patientrecords where rridprefix = NEW.rridprefix and rrid = NEW.rrid); 

    -- if the composite key to be introduced during merge exists, rearrange the data for insert 
    IF @EXIST_COMPOSITE_KEY > 0 
    THEN 

    -- set the incoming column data this way (if composite key exists) 

    -- the legacy duplicate rrid field will help us keep the bad data 
    SET NEW.legacyduperrid = NEW.rrid; 

    -- allow the following block to set the new rrid appropriately 
    SET NEW.rrid = null; 

    END IF; 

    -- legacy code tried set the rrid (race condition), now the db does it 
    SET NEW.rrid = (
    SELECT if(NEW.rrid is null and NEW.legacyduperrid is null, IFNULL(MAX(rrid), 0) + 1, NEW.rrid) 
    FROM patientrecords 
    WHERE rridprefix = NEW.rridprefix 
); 
END 
संबंधित मुद्दे