带有游标和准备语句问题的过程:您的 SQL 语法有错误;执行指令;取消分配准备 stmt; END L' 在第 34 行
Procedure with cursor and prepared statement problem: You have an error in your SQL syntax; EXECUTE stmt; DEALLOCATE PREPARE stmt; END L' at line 34
我有一个在 10.3.28-MariaDB
中工作的过程,但在 MySQL 5.7.26
中我发现了一些问题。该过程获取所有 procedures/functions,在某个日期后更改,并将对它们的执行权限授予特定用户。
CREATE PROCEDURE ExecuteGrantsForModifiedProcedures(IN p_schema varchar(120),
IN p_mysqlUser varchar(120),
IN p_fromModificationDate datetime)
BEGIN
DECLARE v_done INT DEFAULT FALSE;
DECLARE v_statement TEXT;
# Get all the modified procedures/functions
DECLARE cur1 CURSOR FOR SELECT CONCAT('GRANT EXECUTE ON PROCEDURE `', ROUTINE_SCHEMA, '`.`', routine_name, '` TO ',
p_mysqlUser, ';')
FROM information_schema.routines
where routine_schema = p_schema
AND ROUTINE_TYPE = 'PROCEDURE'
AND date(LAST_ALTERED) >= date(p_fromModificationDate)
UNION
SELECT CONCAT('GRANT EXECUTE ON FUNCTION `', ROUTINE_SCHEMA, '`.`', routine_name, '` TO ',
p_mysqlUser, ';')
FROM information_schema.routines
where routine_schema = p_schema
AND ROUTINE_TYPE = 'FUNCTION'
AND date(LAST_ALTERED) >= date(p_fromModificationDate);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
SET max_sp_recursion_depth = 1024;
OPEN cur1;
read_loop:
LOOP
FETCH cur1 INTO v_statement;
IF v_done THEN
LEAVE read_loop;
END IF;
PREPARE stmt FROM v_statement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur1;
end;
MySQL 在我尝试 运行 过程创建语句时显示错误:
[1064] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'v_statement; EXECUTE stmt; DEALLOCATE PREPARE stmt; END L' at line 34
在MySQL中,在PREPARE
中只能使用用户定义的变量。所以删除 v_statement
声明并在所有地方使用 @v_statement
代替:
CREATE PROCEDURE ExecuteGrantsForModifiedProcedures(IN p_schema varchar(120),
IN p_mysqlUser varchar(120),
IN p_fromModificationDate datetime)
BEGIN
DECLARE v_done INT DEFAULT FALSE;
DECLARE v_statement TEXT;
# Get all the modified procedures/functions
DECLARE cur1 CURSOR FOR SELECT CONCAT('GRANT EXECUTE ON PROCEDURE `', ROUTINE_SCHEMA, '`.`', routine_name, '` TO ',
p_mysqlUser, ';')
FROM information_schema.routines
where routine_schema = p_schema
AND ROUTINE_TYPE = 'PROCEDURE'
AND date(LAST_ALTERED) >= date(p_fromModificationDate)
UNION
SELECT CONCAT('GRANT EXECUTE ON FUNCTION `', ROUTINE_SCHEMA, '`.`', routine_name, '` TO ',
p_mysqlUser, ';')
FROM information_schema.routines
where routine_schema = p_schema
AND ROUTINE_TYPE = 'FUNCTION'
AND date(LAST_ALTERED) >= date(p_fromModificationDate);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
SET max_sp_recursion_depth = 1024;
OPEN cur1;
read_loop:
LOOP
FETCH cur1 INTO v_statement;
IF v_done THEN
LEAVE read_loop;
END IF;
SET @v_statement := v_statement;
PREPARE stmt FROM @v_statement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur1;
end
我有一个在 10.3.28-MariaDB
中工作的过程,但在 MySQL 5.7.26
中我发现了一些问题。该过程获取所有 procedures/functions,在某个日期后更改,并将对它们的执行权限授予特定用户。
CREATE PROCEDURE ExecuteGrantsForModifiedProcedures(IN p_schema varchar(120),
IN p_mysqlUser varchar(120),
IN p_fromModificationDate datetime)
BEGIN
DECLARE v_done INT DEFAULT FALSE;
DECLARE v_statement TEXT;
# Get all the modified procedures/functions
DECLARE cur1 CURSOR FOR SELECT CONCAT('GRANT EXECUTE ON PROCEDURE `', ROUTINE_SCHEMA, '`.`', routine_name, '` TO ',
p_mysqlUser, ';')
FROM information_schema.routines
where routine_schema = p_schema
AND ROUTINE_TYPE = 'PROCEDURE'
AND date(LAST_ALTERED) >= date(p_fromModificationDate)
UNION
SELECT CONCAT('GRANT EXECUTE ON FUNCTION `', ROUTINE_SCHEMA, '`.`', routine_name, '` TO ',
p_mysqlUser, ';')
FROM information_schema.routines
where routine_schema = p_schema
AND ROUTINE_TYPE = 'FUNCTION'
AND date(LAST_ALTERED) >= date(p_fromModificationDate);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
SET max_sp_recursion_depth = 1024;
OPEN cur1;
read_loop:
LOOP
FETCH cur1 INTO v_statement;
IF v_done THEN
LEAVE read_loop;
END IF;
PREPARE stmt FROM v_statement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur1;
end;
MySQL 在我尝试 运行 过程创建语句时显示错误:
[1064] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'v_statement; EXECUTE stmt; DEALLOCATE PREPARE stmt; END L' at line 34
在MySQL中,在PREPARE
中只能使用用户定义的变量。所以删除 v_statement
声明并在所有地方使用 @v_statement
代替:
CREATE PROCEDURE ExecuteGrantsForModifiedProcedures(IN p_schema varchar(120),
IN p_mysqlUser varchar(120),
IN p_fromModificationDate datetime)
BEGIN
DECLARE v_done INT DEFAULT FALSE;
DECLARE v_statement TEXT;
# Get all the modified procedures/functions
DECLARE cur1 CURSOR FOR SELECT CONCAT('GRANT EXECUTE ON PROCEDURE `', ROUTINE_SCHEMA, '`.`', routine_name, '` TO ',
p_mysqlUser, ';')
FROM information_schema.routines
where routine_schema = p_schema
AND ROUTINE_TYPE = 'PROCEDURE'
AND date(LAST_ALTERED) >= date(p_fromModificationDate)
UNION
SELECT CONCAT('GRANT EXECUTE ON FUNCTION `', ROUTINE_SCHEMA, '`.`', routine_name, '` TO ',
p_mysqlUser, ';')
FROM information_schema.routines
where routine_schema = p_schema
AND ROUTINE_TYPE = 'FUNCTION'
AND date(LAST_ALTERED) >= date(p_fromModificationDate);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
SET max_sp_recursion_depth = 1024;
OPEN cur1;
read_loop:
LOOP
FETCH cur1 INTO v_statement;
IF v_done THEN
LEAVE read_loop;
END IF;
SET @v_statement := v_statement;
PREPARE stmt FROM @v_statement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur1;
end