Mam bardzo proste pytanie, ale nie otrzymałem żadnego prostego kodu do wyjścia z SP przy użyciu MySQL. Czy ktoś może mi powiedzieć, jak to zrobić?
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;
mysql
sql
stored-procedures
Joe Ijam
źródło
źródło
IF tablename IS NOT NULL THEN
...;)Odpowiedzi:
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;
źródło
END proc_label;
składnia (pokazana w większości oficjalnych przykładów MySQL) nie jest potrzebna. (to świetny sposób na skomentowanie przechowywanego procesu bez konieczności przewijania do dołu w celu wprowadzenia*/
)LEAVE this_proc;
brzmi idealnie!:
i,BEGIN
jakproc_label:BEGIN
podał błąd składni podczasproc_label: BEGIN
pracy.Jeśli chcesz „wcześniejszego wyjścia” w sytuacji, w której nie wystąpił błąd, użyj zaakceptowanej odpowiedzi przesłanej przez @piotrm. Najczęściej jednak wyskakuje błąd z powodu błędu (szczególnie w procedurze SQL).
Od wersji MySQL v5.5 możesz zgłosić wyjątek. Negowanie obsługi wyjątków itp., Które dadzą ten sam wynik, ale w czystszy, bardziej przejmujący sposób.
Oto jak:
DECLARE CUSTOM_EXCEPTION CONDITION FOR SQLSTATE '45000'; IF <Some Error Condition> THEN SIGNAL CUSTOM_EXCEPTION SET MESSAGE_TEXT = 'Your Custom Error Message'; END IF;
Uwaga
SQLSTATE '45000'
oznacza „Nieobsłużony warunek wyjątku zdefiniowanego przez użytkownika”. Domyślnie spowoduje to wyświetlenie kodu błędu1644
(co ma to samo znaczenie). Zauważ, że możesz zgłosić inne kody warunków lub kody błędów, jeśli chcesz (plus dodatkowe szczegóły dotyczące obsługi wyjątków).Więcej na ten temat znajdziesz w:
https://dev.mysql.com/doc/refman/5.5/en/signal.html
Jak zgłosić błąd w funkcji MySQL
http://www.databasejournal.com/features/mysql/mysql-error-handling-using-the-signal-and-resignal-statements.html
Uzupełnienie
Kiedy ponownie czytam ten post, zdałem sobie sprawę, że mam coś więcej do dodania. Przed MySQL v5.5 istniał sposób na emulację zgłaszania wyjątku. To nie jest dokładnie to samo, ale to był analog: Utwórz błąd, wywołując procedurę, która nie istnieje. Nazwij procedurę, używając nazwy, która jest znacząca, aby uzyskać przydatne środki umożliwiające określenie, na czym polegał problem. Gdy wystąpi błąd, zobaczysz linię niepowodzenia (w zależności od kontekstu wykonania).
Na przykład:
CALL AttemptedToInsertSomethingInvalid;
Zauważ, że kiedy tworzysz procedurę, na takich rzeczach nie jest wykonywana walidacja. Tak więc, podczas gdy w czymś takim jak język kompilowany nigdy nie można wywołać funkcji, której nie było, w takim skrypcie po prostu zakończy się niepowodzeniem w czasie wykonywania, co jest dokładnie tym, co jest pożądane w tym przypadku!
źródło
Aby poradzić sobie z tą sytuacją w sposób przenośny (tj. Będzie działać na wszystkich bazach danych, ponieważ nie używa etykiety MySQL Kung fu), podziel procedurę na części logiczne, takie jak ta:
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;
źródło
Dlaczego nie to:
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20)) BEGIN IF tablename IS NOT NULL THEN #proceed the code END IF; # Do nothing otherwise END;
źródło
if
instrukcji. Jest to logicznie identyczne z „wczesnym powrotem”.To działa dla mnie:
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
źródło
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;
źródło