2016-06-18 15 views
0

私は以下のmysqlストアドプロシージャを書いています。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_STATEまたはMYSQL_ERROR_CODE OR MESSAGE_TEXTのいずれも取得できません。彼らはすべて値nullを得ます。

私は最初にロールバックを呼び出しているのですか?そして、それはどういうわけかすべての関連情報を駄目にするのですか?

+0

downvoteを説明してください。 – Paras

+2

試してみてください: 'スタティック診断状態1 @sqlstate = RETURNED_SQ ...'。 [14.6.7.3 GET DIAGNOSTICS構文](https://dev.mysql.com/doc/refman/5.7/en/get-diagnostics.html)を参照してください。 – wchiquito

+1

スタッキングされた診断が私のために働いた。ありがとう!私はドキュメントを読んで、この行に気付きました: "キーワードSTACKEDは、現在のコンテキストが条件ハンドラである場合にのみ利用可能な第2の診断領域から情報を取得することを意味します。出口ハンドラが条件ハンドラであると言うのは正しいですか?これは愚かな質問かもしれません。私はちょうどSQL ServerからMySQLに移行し始めたので、たくさんの愚かな質問をしています。 –

答えて

-1

あなたのスクリプトにDELIMITERを追加していないようです。

DELIMITER |

あなたが.. .. ..

区切り文字をコーディングします。

ありがとうございました

+0

投票が遅れています。これは問題ではありません。提供されるスクリプトは、MySQLワークベンチの "Stored Procedure ..."オプションからのものと思われます。区切り文字は除外されます。 –