请帮助我查询: 我在oracle中有下面提到的存储过程,我需要将它转换为MySQL
CREATE OR REPLACE procedure EAMP.EXEC_DDL (SQLSTMT VARCHAR2) AUTHID DEFINER
is
BEGIN
EXECUTE IMMEDIATE SQLSTMT
END EXEC_DDL;
/
这是我在MySQL(版本5.7)中创建的:
DROP PROCEDURE IF EXISTS EXEC_DDL;
CREATE DEFINER=`ampd_own`@`%`
PROCEDURE `ampd01`.`EXEC_DDL`(in SQLSTMT VARCHAR(4000))
BEGIN
set @sql = SQLSTMT;
PREPARE STMT FROM @sql;
EXECUTE STMT;
deallocate prepare STMT;
END;
但它给了我下面提到的错误:
20:08:43 START Executing, Database Connection: EAMP DEV MYSQL Database Type: MYSQL Catalog: ampd01 Schema: null
20:08:47 INFO Physical database connection acquired for: EAMP DEV MYSQL
20:08:47 WARNING [DROP - 0 rows, 0.994 secs] OK. No rows were affected
SQLWarning:
Code: 1305 SQL State: 42000 --- PROCEDURE ampd01.EXEC_DDL does not exist
DROP PROCEDURE IF EXISTS EXEC_DDL;
20:08:48 FAILED [CREATE - 0 rows, 1.245 secs] [Code: 1064, SQL State:
42000] 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 ''
at line 4
CREATE DEFINER=`ampd_own`@`%`
PROCEDURE `ampd01`.`EXEC_DDL`(in SQLSTMT VARCHAR(4000))
BEGIN
set @sql = SQLSTMT;
20:08:49 FAILED [PREPARE - 0 rows, 1.243 secs] [Code: 1064, SQL State:
42000] 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
'NULL' at line 1
PREPARE STMT FROM @sql;
20:08:51 FAILED [EXECUTE - 0 rows, 1.253 secs] [Code: 1243, SQL State:
HY000] Unknown prepared statement handler (STMT) given to EXECUTE
EXECUTE STMT;
20:08:52 FAILED [DEALLOCATE - 0 rows, 1.255 secs] [Code: 1243, SQL State:
HY000] Unknown prepared statement handler (STMT) given to DEALLOCATE
PREPARE
deallocate prepare STMT;
20:08:53 FAILED [END - 0 rows, 1.253 secs] [Code: 1064, SQL State: 42000]
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 'END' at line 1
END;
20:08:55 END Execution 6 statement(s) executed, 0 row(s) affected,
exec/fetch time: 7.243/0.000 secs [1 successful, 1 Warnings, 5 errors]*/
答案 0 :(得分:0)
在过程体中使用分号,我们需要更改会话的语句分隔符。
例如:
DELIMITER $$
CREATE PROCEDURE foo()
BEGIN
SELECT NOW();
END$$
DELIMITER ;
这样,存储过程中出现的分号不会结束CREATE
语句。我们可以在完成后将语句分隔符更改为分号。
修改的
以下是对报告输出的分析:
本声明
DROP PROCEDURE IF EXISTS EXEC_DDL;
成功完成,发出警告"程序不存在"
执行的下一个声明是:
CREATE DEFINER=`ampd_own`@`%`
PROCEDURE `ampd01`.`EXEC_DDL`(in SQLSTMT VARCHAR(4000))
BEGIN
set @sql = SQLSTMT;
MySQL返回语法错误;这是预期的行为,因为它不是有效的SQL语句。下一个声明已执行:
PREPARE STMT FROM @sql;
返回错误,因为@sql
评估为NULL
。下一个语句已执行
EXECUTE STMT;
失败,因为STMT不是有效的语句句柄。 (因为PREPARE失败了。)
我们不希望将SET
和PREPARE
作为单独的语句执行,我们希望这些语句成为CREATE PROCEDURE
语句的一部分。
问题是分号字符是语句终止符;我们需要将语句终止符更改为其他字符串,而不是在CREATE PROCEDURE
的正文中出现的字符串。
关注
参考:https://dev.mysql.com/doc/refman/5.7/en/stored-programs-defining.html
这是使用MySQL命令行客户端
的演示# mysql --defaults-extra-file=/opt/mysql/scripts/config.cnf --database test
mysql> DELIMITER $$
mysql> DROP PROCEDURE IF EXISTS foo $$
Query OK, 0 rows affected (0.06 sec)
mysql> DROP PROCEDURE IF EXISTS foo $$
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE PROCEDURE foo()
-> BEGIN
-> SELECT NOW();
-> END$$
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL foo();
+---------------------+
| NOW() |
+---------------------+
| 2018-06-13 13:33:33 |
+---------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> exit