簡體   English   中英

MySQL 游標不適用於存儲過程

[英]MySQL cursor not working with Stored Procedure

我在mysql中編寫了存儲過程。 步驟是按照這個網站http://www.mysqltutorial.org/mysql-cursor/但它不起作用。 這是代碼


DELIMITER $$

USE `hr`$$

DROP PROCEDURE IF EXISTS `at_getShift`$$

CREATE DEFINER=`root`@`%` PROCEDURE `at_getShift`()

BEGIN

    DECLARE finished BOOLEAN DEFAULT FALSE;
    DECLARE employeeID VARCHAR(255);-- Default "";

    -- declare cursor for employee email
    DECLARE hrEmployee CURSOR FOR SELECT EmployeeID FROM h_employees WHERE EmployeeID IN ('100013', '100014');

    -- declare NOT FOUND handler
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = TRUE;

    DROP TABLE IF EXISTS temp;
    CREATE TABLE IF NOT EXISTS temp(
      `Code` VARCHAR(255)
    );  

    OPEN hrEmployee;

    get_employee: LOOP
    FETCH hrEmployee INTO employeeID;
    INSERT INTO temp(`Code`) VALUE (employeeID);
    -- If no any row, leave loop
    IF finished THEN 
        INSERT INTO temp(`Code`) VALUE ("112");
        CLOSE hrEmployee;
        LEAVE get_employee;
    END IF;

    -- insert temp
    INSERT INTO temp(`Code`) VALUE ("111");
    END LOOP get_employee;

    SELECT * FROM temp;
END$$

DELIMITER ;

執行: CALL at_getShift();

結果是:

臨時表中的 2 行(1 空,1 是 112)

請幫助我解決這個問題。

在 MySQL 存儲程序中的 SQL 語句中,對過程變量的引用優先於對列的引用。

也就是說,當 SQL 語句中的標識符與過程變量匹配時,SQL 語句將引用該過程變量。

使用表名或表別名限定的引用引用表中的列,即使存在同名的過程變量也是如此。

示范:

 CREATE TABLE emp (id INT);
 INSERT INTO emp (id) VALUES (101),(102);

 DELIMITER $$


 CREATE PROCEDURE foo()
 BEGIN
   DECLARE id INT DEFAULT 3;

   -- this query returns 3 for all rows in emp
   -- because "id" is a reference to the procedure variable
   SELECT id FROM emp WHERE id = 3;

   -- this query returns no rows
   -- because "id" is a reference to the procedure variable
   SELECT id FROM emp WHERE id = 101;

   -- this query references columns in the table because
   -- references to "id" are qualified
   SELECT t.id FROM emp t WHERE t.id = 101;

 END$$

 DELIMITER ;


 CALL foo;

第一個查詢從 emp 返回所有行的過程變量值

    id
 -----
     3
     3

第二個查詢不返回任何行

    id
 -----

第三個查詢返回表中的引用“id”列:

    id
 -----
   101 

外賣是兩個“最佳實踐”:

  • 限定過程中 SQL 語句中的所有列引用

  • 過程變量名應該與列名不同,通常的模式是在變量上使用不同的前綴。 舉個簡單的例子: v_idv_name等。

這兩種做法都使人類讀者更容易破譯程序。

過程變量的獨特命名確實減少了沖突的機會,但不會使限定 SQL 語句中所有列引用的“最佳實踐”無效。 這兩者都有助於使人類讀者更清楚作者的意圖。


編輯:

我試圖回答我以為你在問的問題......“為什么我的程序沒有按照我的預期進行?”。

除了您提出的問題的答案之外……您的程序似乎正在執行的操作(用一組行填充臨時表)通過將行作為一組處理,可以更快、更有效地執行該操作,而不是而不是為每一行發出低效的單獨插入語句。 在性能方面,一個游標循環處理 RBAR(row-by-agonizing-row)會吃掉你的午餐。 還有你的午餐盒。

DELIMITER $$

CREATE PROCEDURE `at_getShift_faster`()
BEGIN
   -- ignore warning message when dropping a table that does not exist
   DECLARE CONTINUE HANDLER FOR 1305 BEGIN END;
   DROP TABLE IF EXISTS temp;
   CREATE TABLE IF NOT EXISTS temp(`Code` VARCHAR(255));  

   INSERT INTO temp (`Code`)  
     SELECT h.EmployeeID 
       FROM h_employees h
      WHERE h.EmployeeID IN ('100013', '100014')
   ;

   SELECT * FROM temp;
END$$

DELIMITER ;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM