MySQL-저장 프로 시저에서 종료 / 종료하는 방법


131

매우 간단한 질문이 있지만 Mysql을 사용하여 SP에서 종료하는 간단한 코드를 얻지 못했습니다. 누구든지 그 방법을 나와 공유 할 수 있습니까?

CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
     IF tablename IS NULL THEN
          #Exit this stored procedure here
     END IF;

     #proceed the code
END;

1
또는 IF tablename IS NOT NULL THEN...;)을 사용할 수 있습니다
OMG Ponies

4
나는 지름길을 잘 잡으려고 노력하고 있습니다 ... 그렇지 않으면 IF 문 내부에서 코드를 작성해야합니다.
Joe Ijam

답변:


204
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
proc_label:BEGIN
     IF tablename IS NULL THEN
          LEAVE proc_label;
     END IF;

     #proceed the code
END;

1
큰! 심지어 END proc_label;(공식적인 MySQL 예제에서 보여지는) 구문이 필요하지 않다는 것을 지적하기까지합니다. (이것은 */제자리 에 놓기 위해 맨 아래로 스크롤하지 않고도 저장된 proc을 주석 처리하는 좋은 방법입니다 )

2
당신은 떠날 가치를 가질 수 있습니까?
ygaradon

35
모든 proc 'this_proc'의 BEGIN 섹션에 레이블을 지정하십시오. LEAVE this_proc;완벽하게 들리기 때문에 !
SNag

@ygaradon 저장 프로시 저는 값을 반환하지 않습니다. 당신은 저장 사용해야하는 기능을 하고 return <value>값을 반환 할 수 있습니다.
David Harkness

1
나는 사이의 공간이 필요하다고 생각 :하고 BEGIN같이 proc_label:BEGIN있는 동안 구문 오류를 준 proc_label: BEGIN했다.
Umair Malhi

13

오류가없는 상황에 대해 "조기 종료"를 원하면 @piotrm이 게시 한 승인 된 답변을 사용하십시오. 그러나 가장 일반적으로 오류 조건 (특히 SQL 프로 시저)으로 인해 맹렬한 상태가됩니다.

MySQL v5.5부터는 예외가 발생할 수 있습니다. 동일한 결과를 얻을 수 있지만 더 깔끔하고 더 강력한 방식으로 예외 처리기 등을 부정하는 것.

방법은 다음과 같습니다.

DECLARE CUSTOM_EXCEPTION CONDITION FOR SQLSTATE '45000';

IF <Some Error Condition> THEN      
    SIGNAL CUSTOM_EXCEPTION
    SET MESSAGE_TEXT = 'Your Custom Error Message';
END IF;     

참고 SQLSTATE '45000'는 "처리되지 않은 사용자 정의 예외 조건"과 같습니다. 기본적으로이 오류 코드는 1644동일한 의미를 갖습니다. 원하는 경우 다른 조건 코드 또는 오류 코드를 던질 수 있습니다 (예외 처리에 대한 추가 세부 사항 포함).

이 주제에 대한 자세한 내용은 다음을 확인하십시오.

https://dev.mysql.com/doc/refman/5.5/en/signal.html

MySQL 함수 내에서 오류를 발생시키는 방법

http://www.databasejournal.com/features/mysql/mysql-error-handling-using-the-signal-and-resignal-statements.html

추가

이 게시물을 다시 읽으면서 추가 할 것이 있다는 것을 깨달았습니다. MySQL v5.5 이전에는 예외 발생을 모방하는 방법이있었습니다. 정확히 같은 것은 아니지만 이것은 아날로그입니다. 존재하지 않는 프로 시저를 호출하여 오류를 작성하십시오. 문제가 무엇인지 확인하는 데 유용한 수단을 얻기 위해 의미있는 이름으로 프로 시저를 호출하십시오. 오류가 발생하면 (실행 컨텍스트에 따라) 실패 라인을 보게됩니다.

예를 들면 다음과 같습니다.

CALL AttemptedToInsertSomethingInvalid;

프로 시저를 작성할 때 해당 항목에 대해 유효성 검증이 수행되지 않습니다. 따라서 컴파일 된 언어와 같은 경우에는 존재하지 않는 함수를 호출 할 수 없으며 이와 같은 스크립트에서는 런타임에 단순히 실패합니다.이 경우 정확히 원하는 것입니다!


1
이것은 나에게 가장 정확하고 철저한 대답처럼 느껴지며 내가 원하는 것입니다. OP와 마찬가지로 실행해야 할 여러 테스트 (입력 유효성 검사)가 있으며 모두 중첩하고 싶지 않기 때문에 잘 작동합니다.
Fodagus

12

이 상황을 이식 가능한 방식으로 처리하려면 (즉, MySQL 레이블 Kung fu를 사용하지 않기 때문에 모든 데이터베이스에서 작동) 다음과 같이 절차를 논리 부분으로 나눕니다.

CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
     IF tablename IS NOT NULL THEN
         CALL SP_Reporting_2(tablename);
     END IF;
END;

CREATE PROCEDURE SP_Reporting_2(IN tablename VARCHAR(20))
BEGIN
     #proceed with code
END;

7
Yucks, 대신 첫 번째 솔루션을 사용하지 않겠습니까?
Pacerier

1
이 투표를 두 번 할 수 있으면 좋겠다. SQL이 실제 프로그래밍 언어가 아니기 때문에 한 번의 절차로 200 줄 이상의 코드를 작성할 수있는 이유는 없습니다.
맥스 하이버

이 답변이 잘못 되었습니까? 아니면 뭔가 빠졌습니까? 공감대가있는 이유는 무엇입니까? 허용 된 솔루션으로이를 입증 할 수있는 방법이 분명히 있습니다.
jlh

@ jlh mysql의 레이블 기술에 대해 몰랐다는 점 에서 잘못되었습니다 (텍스트가 수정되었습니다). 그러나 코드가 잘못되지 않았습니다. 실제로 모든 DB에서 작동합니다.
보헤미안

2

왜 그렇지 않습니까?

CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
     IF tablename IS NOT NULL THEN
          #proceed the code
     END IF;
     # Do nothing otherwise
END;

7
코드가 매우 길다. 이것을 사용할 수 없다 ... 그것은 단지 샘플 일 뿐이다.
Joe Ijam

길이에 관계없이 실행되지 않습니다.
Stephen

들여 쓰기가 걱정되는 경우 if명세서 의 전체 섹션을 들여 쓰지 마십시오 . 논리적으로 "이른 반품"과 동일합니다.
bobobobo 2016

@bobobobo, 그는 자신의 경우이 SQL 제한 주위의 논리를 다시 연결하지 않는 것이 논리적으로 훨씬 더 의미 가 있다고 말합니다 .
Pacerier

1
"if x IS NULL THEN SETresult = -1"이면 많은 검사로 로그인했을 수 있습니다. 당신은 정말로 일을 그만두기를 원합니다. if의 복잡성을 줄입니다. {} 소멸
borjab

2

이것은 나를 위해 작동합니다 :

 CREATE DEFINER=`root`@`%` PROCEDURE `save_package_as_template`( IN package_id int , 
IN bus_fun_temp_id int  , OUT o_message VARCHAR (50) ,
            OUT o_number INT )
 BEGIN

DECLARE  v_pkg_name  varchar(50) ;

DECLARE  v_pkg_temp_id  int(10)  ; 

DECLARE  v_workflow_count INT(10);

-- checking if workflow created for package
select count(*)  INTO v_workflow_count from workflow w where w.package_id = 
package_id ;

this_proc:BEGIN   -- this_proc block start here 

 IF  v_workflow_count = 0 THEN
   select 'no work flow ' as 'workflow_status' ;
    SET o_message ='Work flow is not created for this package.';
    SET  o_number = -2 ;
      LEAVE this_proc;
 END IF;

select 'work flow  created ' as 'workflow_status' ;
-- To  send some message
SET o_message ='SUCCESSFUL';
SET  o_number = 1 ;

  END ;-- this_proc block end here 

END

0
MainLabel:BEGIN

IF (<condition>) IS NOT NULL THEN
    LEAVE MainLabel;
END IF; 

....code

i.e.
IF (@skipMe) IS NOT NULL THEN /* @skipMe returns Null if never set or set to NULL */
     LEAVE MainLabel;
END IF;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.