2014-03-27
우선 기본적으로 프로시저를 만드는 구문은 아래와 같다.
DELIMITER $$
CREATE PROCEDURE `DB이름`.`프로시저이름`()
    BEGIN
    END$$
DELIMITER ; #"DELIMITER"와 ";" 사이에 한칸 띄우는거 주의
그리고, 프로시저 작성시 동적 쿼리를 사용하여 테이블 이름을 변수로 주었을때,
해당 테이블을 SELECT 하는 도중 해당 테이블이 없다면 오류가 뜨게 된다. 그럴때를 대비한 에러 처리 예제가 아래의 구문이다.
DELIMITER $$

USE `NW_DB`$$

DROP PROCEDURE IF EXISTS `test_procedure`$$

CREATE PROCEDURE `test_procedure`( IN table_name VARCHAR(128) )
BEGIN ​

 DECLARE varSQL VARCHAR(9000); 
 #변수 declare 다음에 핸들러declare 오는 순서 주의
 DECLARE EXIT HANDLER FOR 1146 #테이블이 존재하지 않을 경우 프로시저 종료
  BEGIN
    #없는행 리턴
    SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE  TABLE_SCHEMA = 'tmp_blix'; 
  END;

  SET varSQL = CONCAT("SELECT * FROM ", table_name, " LIMIT 30" );

  SET @s = varSQL;
  PREPARE stmt1 FROM @s;
  EXECUTE stmt1;
    
END$$

DELIMITER ;
불러올때는
CALL NW_DB.test_procedure( 'tmp_table');
식으로 불러오면 된다.

에러 처리 핸들러 대한 좀더 자세한 내용은 아래 링크를 참조 하기 바란다.
링크 : https://dev.mysql.com/doc/refman/5.0/en/declare-handler.html



삭제 대비용 원본글 복사

13.6.7.2 DECLARE ... HANDLER Syntax
DECLARE handler_action HANDLER
    FOR condition_value [, condition_value] ...
    statement

handler_action:
    CONTINUE
  | EXIT
  | UNDO

condition_value:
    mysql_error_code
  | SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION
The DECLARE ... HANDLER statement specifies a handler that deals with one or more conditions. If one of these conditions occurs, the specified statement executes. statement can be a simple statement such as SET var_name = value, or a compound statement written using BEGIN and END (see Section 13.6.1, “BEGIN ... END Compound-Statement Syntax”).

Handler declarations must appear after variable or condition declarations.

The handler_action value indicates what action the handler takes after execution of the handler statement:

CONTINUE: Execution of the current program continues.

EXIT: Execution terminates for the BEGIN ... END compound statement in which the handler is declared. This is true even if the condition occurs in an inner block.

UNDO: Not supported.

The condition_value for DECLARE ... HANDLER indicates the specific condition or class of conditions that activates the handler:

A MySQL error code (a number) or an SQLSTATE value (a 5-character string literal). You should not use MySQL error code 0 or SQLSTATE values that begin with '00', because those indicate success rather than an error condition. For a list of MySQL error codes and SQLSTATE values, see Section B.3, “Server Error Codes and Messages”.

A condition name previously specified with DECLARE ... CONDITION. A condition name can be associated with a MySQL error code or SQLSTATE value. See Section 13.6.7.1, “DECLARE ... CONDITION Syntax”.

SQLWARNING is shorthand for the class of SQLSTATE values that begin with '01'.

NOT FOUND is shorthand for the class of SQLSTATE values that begin with '02'. This is relevant within the context of cursors and is used to control what happens when a cursor reaches the end of a data set. If no more rows are available, a No Data condition occurs with SQLSTATE value '02000'. To detect this condition, you can set up a handler for it (or for a NOT FOUND condition). For an example, see Section 13.6.6, “Cursors”. This condition also occurs for SELECT ... INTO var_list statements that retrieve no rows.

SQLEXCEPTION is shorthand for the class of SQLSTATE values that do not begin with '00', '01', or '02'.

If a condition occurs for which no handler has been declared, the action taken depends on the condition class:

For SQLEXCEPTION conditions, the stored program terminates at the statement that raised the condition, as if there were an EXIT handler. If the program was called by another stored program, the calling program handles the condition using the handler selection rules applied to its own handlers.

For SQLWARNING or NOT FOUND conditions, the program continues executing, as if there were a CONTINUE handler.

The following example uses a handler for SQLSTATE '23000', which occurs for a duplicate-key error:

mysql> CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter //

mysql> CREATE PROCEDURE handlerdemo ()
    -> BEGIN
    ->   DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
    ->   SET @x = 1;
    ->   INSERT INTO test.t VALUES (1);
    ->   SET @x = 2;
    ->   INSERT INTO test.t VALUES (1);
    ->   SET @x = 3;
    -> END;
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x//
    +------+
    | @x   |
    +------+
    | 3    |
    +------+
    1 row in set (0.00 sec)
Notice that @x is 3 after the procedure executes, which shows that execution continued to the end of the procedure after the error occurred. If the DECLARE ... HANDLER statement had not been present, MySQL would have taken the default action (EXIT) after the second INSERT failed due to the PRIMARY KEY constraint, and SELECT @x would have returned 2.

To ignore a condition, declare a CONTINUE handler for it and associate it with an empty block. For example:

DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;
The scope of a block label does not include the code for handlers declared within the block. Therefore, the statement associated with a handler cannot use ITERATE or LEAVE to refer to labels for blocks that enclose the handler declaration. Consider the following example, where the REPEAT block has a label of retry:

CREATE PROCEDURE p ()
BEGIN
  DECLARE i INT DEFAULT 3;
  retry:
    REPEAT
      BEGIN
        DECLARE CONTINUE HANDLER FOR SQLWARNING
          BEGIN
            ITERATE retry;    # illegal
          END;
        IF i < 0 THEN
          LEAVE retry;        # legal
        END IF;
        SET i = i - 1;
      END;
    UNTIL FALSE END REPEAT;
END;
The retry label is in scope for the IF statement within the block. It is not in scope for the CONTINUE handler, so the reference there is invalid and results in an error:

ERROR 1308 (42000): LEAVE with no matching label: retry
To avoid references to outer labels in handlers, use one of these strategies:

To leave the block, use an EXIT handler. If no block cleanup is required, the BEGIN ... END handler body can be empty:

DECLARE EXIT HANDLER FOR SQLWARNING BEGIN END;
Otherwise, put the cleanup statements in the handler body:

DECLARE EXIT HANDLER FOR SQLWARNING
  BEGIN
    block cleanup statements
  END;
To continue execution, set a status variable in a CONTINUE handler that can be checked in the enclosing block to determine whether the handler was invoked. The following example uses the variable done for this purpose:

CREATE PROCEDURE p ()
BEGIN
  DECLARE i INT DEFAULT 3;
  DECLARE done INT DEFAULT FALSE;
  retry:
    REPEAT
      BEGIN
        DECLARE CONTINUE HANDLER FOR SQLWARNING
          BEGIN
            SET done = TRUE;
          END;
        IF done OR i < 0 THEN
          LEAVE retry;
        END IF;
        SET i = i - 1;
      END;
    UNTIL FALSE END REPEAT;
END;