2011-10-07 8 views
10

मैं कर्सर में LIMIT का उपयोग करना चाहता हूं। कर्सर को लूप के भीतर कई बार इस्तेमाल और अद्यतन किया जाना चाहिए, प्रत्येक बार LIMIT के विभिन्न मानकों के साथ। यहाँ कुछ कोड:संग्रहीत प्रक्रिया में गतिशील कर्सर

DELIMITER $$ 
CREATE PROCEDURE `updateIt`() READS SQL DATA 
BEGIN 

declare done int(1) default 0; 
declare counter int(10) default 0; 
declare xabc int(10) default 0; 

declare tab1Cursor cursor for select abc from tab1 limit 100000*counter, 100000; 
declare continue handler for not found set done=1; 

loopCounter: LOOP 
    set done = 0; 
    open tab1Cursor; 
    igmLoop: loop 
     fetch tab1Cursor into xabc; 
     if done = 1 then leave igmLoop; end if; 
     -- do something 
    end loop igmLoop; 
    close tab1Cursor; 

    if (counter = 1039) 
     leave loopCounter; 
    end if; 
    set counter = counter + 1; 

END LOOP loopCounter; 
END $$ 
DELIMITER ; 

लेकिन यह (मैं भी लूप counterLoop में कर्सर के साथ इसे करने की कोशिश) काम नहीं करता। क्या माइस्क्ल गतिशील कर्सर से निपट सकता है?

उत्तर

11

MySQL Manual

एक कर्सर से एक गतिशील बयान है कि तैयार किया जाता है और तैयार और निष्पादित साथ निष्पादित करने के लिए इस्तेमाल नहीं किया जा सकता है। एक कर्सर के लिए कथन कर्सर निर्माण समय पर चेक किया गया है, इसलिए कथन गतिशील नहीं हो सकता है।

हालांकि 2 तरीके हैं।

पहला उन मामलों के लिए है जहां एक समय में केवल एक ही उपयोगकर्ता प्रक्रिया को चलाएगा। गतिशील एसक्यूएल के साथ एक दृश्य बनाने के लिए एक तैयार कथन का उपयोग किया जा सकता है और कर्सर इस स्थिर-नामित दृश्य से चयन कर सकता है। लगभग कोई प्रदर्शन प्रभाव नहीं है। दुर्भाग्यवश, ये विचार अन्य उपयोगकर्ताओं के लिए भी दृश्यमान हैं (अस्थायी दृश्य जैसी कोई चीज़ नहीं है), इसलिए यह एकाधिक उपयोगकर्ताओं के लिए काम नहीं करेगा।

आकस्मिक रूप से, तैयार कथन में एक अस्थायी तालिका बनाई जा सकती है और कर्सर अस्थायी तालिका से चयन कर सकता है। केवल वर्तमान सत्र एक अस्थायी तालिका देख सकता है, इसलिए एकाधिक उपयोगकर्ता समस्या हल हो जाती है। लेकिन इस समाधान में महत्वपूर्ण प्रदर्शन प्रभाव हो सकता है क्योंकि जब भी प्रो चलती है तो एक अस्थायी तालिका बनाई जानी चाहिए।

नीचे पंक्ति: हमें अभी भी गतिशील रूप से बनाए जाने में सक्षम होने के लिए कर्सर की आवश्यकता है!

यहाँ एक दृश्य का उपयोग धन्यवाद mysql forums

DELIMITER // 
DROP PROCEDURE IF EXISTS test_prepare// 

CREATE PROCEDURE test_prepare(IN tablename varchar(255), columnname varchar(50)) 
BEGIN 
DECLARE cursor_end CONDITION FOR SQLSTATE '02000'; 
DECLARE v_column_val VARCHAR(50); 
DECLARE done INT DEFAULT 0; 
DECLARE cur_table CURSOR FOR SELECT * FROM test_prepare_vw; 
DECLARE CONTINUE HANDLER FOR cursor_end SET done = 1; 

SET @query = CONCAT('CREATE VIEW test_prepare_vw as select ', columnname, ' from ', tablename); 
select @query; 
PREPARE stmt from @query; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

OPEN cur_table; 
FETCH cur_table INTO v_column_val; 
WHILE done = 0 DO 
SELECT v_column_val; 
FETCH cur_table INTO v_column_val; 
END WHILE; 
CLOSE cur_table; 

DROP VIEW test_prepare_vw; 

END; 
// 

DELIMITER ; 
+0

से एक कर्सर में तालिका नाम और स्तंभ नाम पारित करने के लिए का एक उदाहरण है। यह मेरी समस्या के लिए काम कर सकता है। मैं कोशिश करता हूँ – Marcus

+1

हजार धन्यवाद @ Pentium10 – gca

+1

इस उत्तर का बड़ा हिस्सा http://forums.mysql.com/read.php?61,116597,226041 से plagarized प्रतीत होता है शायद उचित विशेषता उचित होगी। – Rob