当前位置:   article > 正文

关于MYSQL存储过程/函数中GET DIAGNOSTICS 异常捕捉消息返回问题说明

get diagnostics

在MySQL存储过中处理SQLEXCEPTION的时候,如果你是使用GET CURRENT DIAGNOSTICS CONDITION 1 @SQL_MSG_CODE = RETURNED_SQLSTATE,@SQL_MSG_TEXT = MESSAGE_TEXT;的方式来读取那么每次显示的都是第一次报错的消息,那么如何显示当前最新的报错信息呢?请参照下例:

  1. DROP TABLE IF EXISTS t1;
  2. CREATE TABLE t1 (c1 TEXT NOT NULL);
  3. DROP PROCEDURE IF EXISTS p;
  4. delimiter //
  5. CREATE PROCEDURE p ()
  6. BEGIN
  7. -- Declare variables to hold diagnostics area information
  8. DECLARE errcount INT;
  9. DECLARE errno INT;
  10. DECLARE msg TEXT;
  11. DECLARE EXIT HANDLER FOR SQLEXCEPTION
  12. BEGIN
  13. -- Here the current DA is nonempty because no prior statements
  14. -- executing within the handler have cleared it
  15. GET CURRENT DIAGNOSTICS CONDITION 1
  16. errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  17. SELECT 'current DA before mapped insert' AS op, errno, msg;
  18. GET STACKED DIAGNOSTICS CONDITION 1
  19. errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  20. SELECT 'stacked DA before mapped insert' AS op, errno, msg;
  21. -- Map attempted NULL insert to empty string insert
  22. INSERT INTO t1 (c1) VALUES('');
  23. -- Here the current DA should be empty (if the INSERT succeeded),
  24. -- so check whether there are conditions before attempting to
  25. -- obtain condition information
  26. GET CURRENT DIAGNOSTICS errcount = NUMBER;
  27. IF errcount = 0
  28. THEN
  29. SELECT 'mapped insert succeeded, current DA is empty' AS op;
  30. ELSE
  31. GET CURRENT DIAGNOSTICS CONDITION 1
  32. errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  33. SELECT 'current DA after mapped insert' AS op, errno, msg;
  34. END IF ;
  35. GET STACKED DIAGNOSTICS CONDITION 1
  36. errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  37. SELECT 'stacked DA after mapped insert' AS op, errno, msg;
  38. END;
  39. INSERT INTO t1 (c1) VALUES('string 1');
  40. INSERT INTO t1 (c1) VALUES(NULL);
  41. END;
  42. //
  43. delimiter ;
  44. CALL p();
  45. SELECT * FROM t1;

需要注意的是
1.GET DIAGNOSTICS语句也会清空当前诊断区中的内容,所以上述代码中把condition handler中的insert语句去掉,得到的结果也是一样的
2.如果将上述存储过程进行如下修改,也就是将3条declare变量的语句放到
declare handler中,实际的结果将取决于MySQL的版本,如果是在MySQL-5.7.2之前的版本,下述修改后并不会影响诊断区中的内容,实际结果与上述结果相同,如果实在MySQL-5.7.2及之后的版本,declare变量语句会清空当前诊断区中的内容。

  1. CREATE PROCEDURE p ()
  2. BEGIN
  3. DECLARE EXIT HANDLER FOR SQLEXCEPTION
  4. BEGIN
  5. -- Declare variables to hold diagnostics area information
  6. DECLARE errcount INT;
  7. DECLARE errno INT;
  8. DECLARE msg TEXT;
  9. GET CURRENT DIAGNOSTICS CONDITION 1
  10. errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  11. SELECT 'current DA before mapped insert' AS op, errno, msg;
  12. GET STACKED DIAGNOSTICS CONDITION 1
  13. errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
  14. SELECT 'stacked DA before mapped insert' AS op, errno, msg;
  15. ...

所以在需要获取诊断区中的内容时,一定要从堆栈诊断区中获取,而不是当前诊断区。 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号