Mysql:获取diagnonstic条件返回null

时间:2016-06-18 20:35:37

标签: mysql sql stored-procedures

我写了以下mysql存储过程。

CREATE DEFINER=`clocery`@`%` PROCEDURE `ADMIN_ADD_NEW_USER`(IN `IN_FIRST_NAME` varchar(50),IN `IN_LAST_NAME` varchar(50),IN `IN_USER_NAME` varchar(50), IN `IN_EMAIL` varchar(50),IN `IN_PASSWORD` varchar(80),IN `IN_ROLE` varchar(20),IN `IN_CREATED_BY` INT,OUT `OUT_STATUS` char(1),OUT `OUT_MESSAGE` varchar(200))
BEGIN
    DECLARE logged_in_user_role_id INT;
    DECLARE to_be_created_user_role_id INT;
    DECLARE user_who_created_logged_in_user INT;
    DECLARE matching_row_count_user_name INT;
    DECLARE matching_row_count_user_e_mail INT;

    DECLARE EXIT HANDLER FOR SQLEXCEPTION
        BEGIN
            ROLLBACK;

            GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;

            CALL UTIL_LOG_ERROR( 'ADMIN_ADD_NEW_USER', @sqlState, @errno, @text);

            SELECT 'N', UTIL_GET_ERROR_MESSAGE( 'some-error' )
                INTO OUT_STATUS, OUT_MESSAGE;

    END;

    /**
        * If passed user_id is NULL.
        */
    IF IN_CREATED_BY = NULL THEN
        SELECT 'N', UTIL_GET_ERROR_MESSAGE( 'some-error' ) 
                INTO OUT_STATUS, OUT_MESSAGE;

        CALL LOG_ERROR( 'ADD_NEW_USER', UTIL_GET_ERROR_MESSAGE( 'in-created-by-null' ));

    ELSE 
        SELECT U.ROLE_ID, U.CREATED_BY INTO logged_in_user_role_id, user_who_created_logged_in_user FROM USERS U WHERE U.ID = IN_CREATED_BY;
        SELECT R.ID INTO to_be_created_user_role_id FROM ROLES R WHERE R.ROLE = IN_ROLE;

        /**
            * If user has provided invalid role.
            */
        IF to_be_created_user_role_id = NULL THEN
            SELECT 'N', UTIL_GET_ERROR_MESSAGE( 'in-valid-role-provided' ) INTO OUT_STATUS, OUT_MESSAGE;
        ELSE

            /**
                * Lets' see if logged in user has more authority than the one we are trying to create.
                */
                IF to_be_created_user_role_id <= logged_in_user_role_id THEN
                    SELECT 'N', UTIL_GET_ERROR_MESSAGE( 'permission-denied' ) INTO OUT_STATUS, OUT_MESSAGE;
                    CALL CREATE_NOTIFICATION_FOR_USER( user_who_created_logged_in_user, CONCAT( GET_USER_IDENTIFICATION( IN_CREATED_BY), 'tried to create an account of higher authority.'));

                ELSE 

                    /**
                        * Lets' check if user name already present in the database.
                        */
                        SELECT COUNT(*) INTO matching_row_count_user_name FROM USERS U WHERE U.USER_NAME = IN_USER_NAME;
                        SELECT COUNT(*) INTO matching_row_count_user_e_mail FROM USERS U WHERE U.EMAIL = IN_EMAIL;

                        IF matching_row_count_user_name > 0 THEN
                            SELECT 'N', UTIL_GET_ERROR_MESSAGE('username-exists') INTO OUT_STATUS, OUT_MESSAGE;

                        ELSEIF matching_row_count_user_e_mail > 0 THEN
                            SELECT 'N', UTIL_GET_ERROR_MESSAGE( 'email-exists' ) INTO OUT_STATUS, OUT_MESSAGE;

                        ELSE
                            /**
                                * Now, we are good to insert.
                                */
                                START TRANSACTION;

                                /**
                                    * Inserting into credentials first.
                                    */
                                    INSERT INTO CREDENTIALS( PASSWORD, LOCKED ) VALUES ( IN_PASSWORD, 'N' );
                                    INSERT INTO USERS( F_NAME, L_NAME, USER_NAME, EMAIL, ROLE_ID, ACTIVE, DELETED, CREATED_BY, CREATED_DATE, CREDENTIAL_ID, LAST_ACTOR_ID )
                                                    VALUES( IN_FIRST_NAME, IN_LAST_NAME, IN_USER_NAME, IN_EMAIL, to_be_created_user_role_id, 'Y', 'N', IN_CREATED_BY, NOW(), LAST_INSERT_ID(), IN_CREATED_BY );

                                    INSERT INTO HISTORY_USER_EVENTS( USER_ID, TEXT, TYPE ) VALUES( LAST_INSERT_ID(), 
                                            CONCAT( UTIL_GET_USER_IDENTIFICATION( LAST_INSERT_ID() ), '''s account was created by ', UTIL_GET_USER_IDENTIFICATION( IN_CREATED_BY ), '.'),
                                            UTIL_GET_EVENT_ID_FOR_ACCOUNT_ACTION( 'Created' ));

                                    INSERT INTO HISTORY_ADMIN_EVENTS( ADMIN_ID, TEXT, TYPE ) VALUES( IN_CREATED_BY,
                                            CONCAT( UTIL_GET_USER_IDENTIFICATION( IN_CREATED_BY ), ' created account of ', UTIL_GET_USER_IDENTIFICATION( LAST_INSERT_ID()), ' with role ', IN_ROLE, '.' ),
                                            UTIL_GET_EVENT_ID_FOR_USER_ADDITION( IN_ROLE ));

                                    SELECT 'Y', 'User created.' INTO OUT_STATUS, OUT_MESSAGE;
                                    COMMIT;
                        END IF;
                END IF;


        END IF;

    END IF;

END

如您所见,我创建了一个处理程序,可以在任何SQL异常的情况下执行。该过程应该产生大量的运行时错误。但是,

我无法检索任何RETURNED_SQL_STATEMYSQL_ERROR_CODEMESSAGE_TEXT?他们都获得了价值null

是因为我最初调用rollback吗?它以某种方式弄乱了所有相关信息?

2 个答案:

答案 0 :(得分:0)

以下是回滚代码块的示例,该功能可以将错误记录到其他表中,而不会丢失MySQL中的异常详细信息,并在记录错误后再次抛出错误。您应该在回滚之前进行诊断。

# CREATE PROCEDURE AND OTHER DECLARE STATEMENTS HERE
# ....

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
    GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;

    ROLLBACK;

    SET @full_error = CONCAT('ERR:', @errno, '(', @sqlstate, '):', @text);

    CALL sp_logaction(@full_error); # Some logging procedure

    RESIGNAL;
END;
# PROCEDURE BODY WITH START TRANSACTION & COMMIT HERE
# .....

答案 1 :(得分:-1)

好像你错过了在脚本中添加DELIMITER。

DELIMITER |

你编码...... .. ..

DELIMITER;

由于