2011-10-07 144 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 ; 

然而,這不工作(我還用光標在LOOP counterLoop嘗試過)。 Mysql能處理動態遊標嗎?

回答

11

MySQL Manual

光標不能用於被製備和用 PREPARE和EXECUTE執行的動態語句。遊標創建時檢查遊標的語句是 ,因此語句不能是動態的。

但是有2種方法。

第一種情況是一次只能有一個用戶正在運行該程序。準備語句可用於使用動態SQL創建視圖,並且遊標可從此靜態命名的視圖中進行選擇。幾乎沒有性能影響。不幸的是,這些視圖對其他用戶也是可見的(不存在臨時視圖),所以這對多個用戶不起作用。

類似地,可以在prepare語句中創建一個臨時表,並且遊標可以從臨時表中進行選擇。只有當前會話才能看到臨時表,因此多用戶問題已解決。但是這個解決方案可能會對性能產生重大影響,因爲每次proc運行時都必須創建臨時表。

底線:我們仍然需要光標才能動態創建!

下面是一個使用視圖表名和列名從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。也許適當的歸屬將是適當的。 – Rob