[英]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
外賣是兩個“最佳實踐”:
和
v_id
、 v_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.