我不太熟悉MYSQL函数&异常处理。经过所有的研究,我可以在下面提出,但没有任何收获。
如果insert语句执行失败,否则返回1,则尝试返回0。异常被引发而不是被处理。我哪里出问题了?
CREATE DEFINER=`myusr`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(6)) RETURNS int(1)
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE EXP DATETIME;
DECLARE RINT INT(1);
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
RETURN 0;
END;
SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
INSERT INTO `mydb`.`my_tbl`
(`C1`,
`C2`,
`C3`)
VALUES
(p1, p2, exp);
SET RINT = 1;
RETURN RINT;
END
表- my_tbl
成功案例- func1('ABC','123456')
EXCEPTION CASE - func1('ABC','123456789')
编辑-添加了屏幕截图
发布于 2020-02-22 02:30:32
看来mysql 8.0.19无法捕获所有错误并正确处理它们。
错误代码: 1406。数据太长,不能在第1行的“p2”列中使用
错误代码: 1049。未知数据库“mydb”
我测试了两个例子,但没有成功,其他例子也是如此,我认为这更像是mysql论坛的一个例子。
DELIMITER $$
CREATE DEFINER=`mydb`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(6)) RETURNS int
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE EXP DATETIME;
DECLARE RINT INT(1);
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIn
RETURN 0;
END;
SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
INSERT INTO `mydb`.`func1`
(`C1`,
`C2`,
`C3`)
VALUES
(p1, p2, exp);
SET RINT = 1;
RETURN RINT;
END;
DE§LIMITER ;
这个场景是可行的。我增加了引用变量p2的大小以适应输入的数据,并为错误1265添加了一个退出处理程序,这是在尝试插入长文本时得到的错误。
错误代码: 1265。第1行“c2”列的数据截断
DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `func1`(p1 varchar(50), p2 varchar(20)) RETURNS int
MODIFIES SQL DATA
DETERMINISTIC
BEGIN
DECLARE EXP DATETIME;
DECLARE RINT INT(1);
BEGIN
DECLARE EXIT HANDLER FOR 1265 RETURN 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN 0;
SET exp = DATE_ADD(NOW(), INTERVAL 15 MINUTE);
INSERT INTO `mydb`.`my_tbl`
(`C1`,
`C2`,
`C3`)
VALUES
(p1, p2, exp);
SET RINT = 1;
RETURN RINT;
END;
END$$
DELIMITER ;
所得到的错误,在添加处理程序之前传递错误消息。
发布于 2020-02-22 13:21:15
这里的问题是异常是在异常处理程序之外生成的。在定义异常处理程序之前,将验证发送给该函数的参数。要捕获该异常,需要在调用函数时设置异常处理程序。
如果声明了p2 varchar(20),并保留了列定义varchar(6),则可能会得到所需的行为,因为异常将在异常处理程序所涵盖的代码中触发。
发布于 2020-02-22 09:56:47
TRY语句的作用是捕获异常。(因为这个过程通常包含几个语句,所以通常使用术语“TRY块”而不是“TRY语句”)。如果在TRY块中发生异常,系统中称为异常处理程序的部分将异常传递给程序的另一部分,该部分将处理异常。这个程序部分由关键字CATCH表示,因此称为CATCH块。
备注
使用TRY和CATCH语句进行异常处理是现代编程语言(如C#和Java )处理错误的常见方式。
尝试和捕获块的异常处理给程序员带来了很多好处,如:
Exceptions provide a clean way to check for errors without cluttering code
Exceptions provide a mechanism to signal errors directly rather than using some side effects
Exceptions can be seen by the programmer and checked during the compilation process
Server 2012引入了与处理错误有关的第三条语句:抛出。此语句允许您抛出在异常处理块中捕获的异常。简单地说,抛出语句是另一个返回机制,它的行为类似于已经描述的RAISEERROR语句。
示例1展示了尝试/捕捉/抛出异常处理是如何工作的。它展示了如何使用异常处理插入批处理中的所有语句,或者在发生错误时回滚整个语句组。此示例基于部门和员工表之间的引用完整性。因此,必须使用主键和外键约束创建两个表。
例1
0270_001
在示例1中执行批处理之后,批处理中的所有三个语句都不会被执行,这个示例的输出是:
0271_001
示例1的执行如下所示。成功执行第一个INSERT语句。然后,第二条语句导致引用完整性错误。因为所有三个语句都是在TRY块中编写的,所以异常将被“抛出”,异常处理程序将启动CATCH块。CATCH回滚所有语句并打印相应的消息。之后,抛出语句将批处理的执行返回给调用者。因此,employee表的内容不会更改。
备注
语句开始事务、提交事务和回滚涉及事务的Transact-SQL语句。这些语句分别启动、提交和回滚事务。关于这些陈述和交易的一般讨论,见第13章。
https://stackoverflow.com/questions/60350960
复制