저장 프로세스 문법
13825 단어 예외 처리유표저장 프로세스 문법
① 변수에 대한 설명:
DECLARE var_name[,...] type [DEFAULT value]
이 문장은 국부 변수를 성명하는 데 쓰인다.변수에 기본값을 지정하려면 DEFAULT 자구가 있어야 합니다.값은 상수가 필요 없는 표현식으로 지정할 수 있습니다.DEFAULT 자구가 없는 경우 초기 값은 NULL입니다.
국부 변수의 작용 범위가 성명된 BEGIN에서...END 블록 내그것은 같은 이름으로 변수를 설명하는 블록을 제외하고는 끼워 넣은 블록에 사용할 수 있다.② 변수 지정:
A: SET 문 사용:
SET var_name = expr [, var_name = expr]...
SET 대신 문을 사용하여 사용자 변수에 값을 지정할 수도 있습니다.이 경우 SET 이외의 문에서는 =이 비교 연산자로 간주되므로 다음과 같이 할당자는 =이어야 합니다.
mysql> SET @t1=0, @t2=0,@t3=0;
mysql> SELECT @t1:=0,@t2:=0,@t3:=0;
사용
select
문장이 변수에 값을 부여하는 경우, 결과가 비어 있으면
, 즉 기록이 없다. 이때 변수의 값은 지난번 변수가 값을 부여했을 때의 값이다. 예를 들어
만약 변수에 값을 부여하지 않았다면
NULL
.
B:SELECT 사용...INTO 문:
SELECT col_name[,...] INTO var_name[,...]table_expr 이 SELECT 문법은 선택한 열을 변수에 직접 저장합니다.따라서 단일한 줄만 되찾을 수 있다.
예: SELECT id, data INTO x, y FROM test.t1 LIMIT 1; 2. 베인...END 복합문:
[begin_label:] BEGIN
[statement_list]
END [end_label]
메모리 서브루틴에서 BEGIN을 사용할 수 있습니다...END 복합 문에 여러 문이 포함됩니다.statement_list는 하나 이상의 문장의 목록을 대표합니다.statement_list 안의 모든 문장은 반드시 분호를 사용해야 한다(;)자, 마무리.
복합문은 태그가 될 수 있습니다.Begin 을 제외하고는label이 존재하지 않으면 endlabel은 주어질 수 없고, 만약 둘 다 존재한다면, 그들은 반드시 같아야 한다.
3. 프로세스 제어:
① IF 문:
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list] ...
[ELSE statement_list]
END IF
IF는 기본적인 조건 구조를 실현했다.하면, 만약, 만약...condition 값이 진짜이고 해당 SQL 문 목록이 실행됩니다.검색이 없으면condition이 일치하며 ELSE 자문에서 문 목록이 실행됩니다.statement_list는 한 개 이상의 문장을 포함할 수 있습니다.
예: student 테이블:
mysql> select * from student;
+---------------+---------------+----------------------+-----------+----+
| nickname | password | email | address | id |
+---------------+---------------+----------------------+-----------+----+
| elgin | 12345 | [email protected] | xinbei9-2 | 1 |
| elgin | 12345 | [email protected] | xinbei9-2 | 2 |
| seth | 12345 | [email protected] | xinbei9-2 | 3 |
| 3344 | ddff3322 | [email protected] | xinbei9-2 | 4 |
| ddddfff | procedure1234 | [email protected] | xinbei9-2 | 5 |
| jdbcName | jdbc1234 | [email protected] | xinbei9-2 | 6 |
| testProcedure | procedure1234 | [email protected] | china.js | 7 |
| jdbcName | jdbc1234 | [email protected] | china.js | 9 |
+---------------+---------------+----------------------+-----------+----+
8 rows in set
프로세스 제어를 사용하는 스토리지 프로세스:mysql> create procedure testif(sid varchar(10))
-> begin
-> if sid='01' then
-> select * from student where id=1;
-> elseif sid='02' then
-> select * from student where id=2;
-> else
-> select * from student where id=7;
-> end if;
-> end;
Query OK, 0 rows affected
호출 결과:mysql> call testif('01');
+----------+----------+---------------+-----------+----+
| nickname | password | email | address | id |
+----------+----------+---------------+-----------+----+
| elgin | 12345 | [email protected] | xinbei9-2 | 1 |
+----------+----------+---------------+-----------+----+
1 row in set
Query OK, 0 rows affected
mysql> call testif('02');
+----------+----------+---------------+-----------+----+
| nickname | password | email | address | id |
+----------+----------+---------------+-----------+----+
| elgin | 12345 | [email protected] | xinbei9-2 | 2 |
+----------+----------+---------------+-----------+----+
1 row in set
Query OK, 0 rows affected
mysql> call testif(null);
+---------------+---------------+----------------------+----------+----+
| nickname | password | email | address | id |
+---------------+---------------+----------------------+----------+----+
| testProcedure | procedure1234 | [email protected] | china.js | 7 |
+---------------+---------------+----------------------+----------+----+
1 row in set
Query OK, 0 rows affected
② CASE 문:
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE
Or:
CASE
WHEN search_condition THEN statement_list
[WHEN search_condition THEN statement_list] ...
[ELSE statement_list]
END CASE
여전히 student표를 사용합니다.mysql> create procedure testcase(sid int)
-> begin
-> declare x int;
-> set x=sid+1;
-> case
-> when 10 then select * from student where id=5;
-> when 10 then select * from student where id=1;
-> else select * from student where id=7;
-> end case;
-> end;
Query OK, 0 rows affected
호출 결과:mysql> call testcase(9);
+----------+----------+---------------+-----------+----+
| nickname | password | email | address | id |
+----------+----------+---------------+-----------+----+
| elgin | 12345 | [email protected] | xinbei9-2 | 1 |
+----------+----------+---------------+-----------+----+
1 row in set
Query OK, 0 rows affected
mysql> call testcase(10);
+----------+---------------+---------------+-----------+----+
| nickname | password | email | address | id |
+----------+---------------+---------------+-----------+----+
| ddddfff | procedure1234 | [email protected] | xinbei9-2 | 5 |
+----------+---------------+---------------+-----------+----+
1 row in set
Query OK, 0 rows affected
mysql> call testcase(6);
+---------------+---------------+----------------------+----------+----+
| nickname | password | email | address | id |
+---------------+---------------+----------------------+----------+----+
| testProcedure | procedure1234 | [email protected] | china.js | 7 |
+---------------+---------------+----------------------+----------+----+
1 row in set
③ WHILE 문:예:
mysql> create procedure testwhile()
-> begin
-> declare x int;
-> set x=5;
-> while x<8 do
-> insert into student(nickname,password,email,address)values('dfg',x,'[email protected]','china.js');
-> set x=x+1;
-> end while;
-> end;
Query OK, 0 rows affected
호출 결과:mysql> call testwhile();
Query OK, 1 row affected
mysql> select * from student
-> ;
+---------------+---------------+----------------------+-----------+----+
| nickname | password | email | address | id |
+---------------+---------------+----------------------+-----------+----+
| elgin | 12345 | [email protected] | xinbei9-2 | 1 |
| elgin | 12345 | [email protected] | xinbei9-2 | 2 |
| seth | 12345 | [email protected] | xinbei9-2 | 3 |
| 3344 | ddff3322 | [email protected] | xinbei9-2 | 4 |
| ddddfff | procedure1234 | [email protected] | xinbei9-2 | 5 |
| jdbcName | jdbc1234 | [email protected] | xinbei9-2 | 6 |
| testProcedure | procedure1234 | [email protected] | china.js | 7 |
| jdbcName | jdbc1234 | [email protected] | china.js | 9 |
| dfg | 5 | [email protected] | china.js | 10 |
| dfg | 6 | [email protected] | china.js | 11 |
| dfg | 7 | [email protected] | china.js | 12 |
+---------------+---------------+----------------------+-----------+----+
11 rows in set
3 개의 레코드 ④ LOOP 문이 삽입되어 있습니다.
LOOP은 특정한 문장이나 문장군의 중복 집행을 허용하여 간단한 순환 구조를 실현한다.루프 내의 문은 루프가 종료될 때까지 반복되며, 일반적으로 LEAVE 문과 함께 종료됩니다.
예:
mysql> create procedure testloop()
-> begin
-> declare x int;
-> set x=5;
-> insertloop:loop
-> insert into student(nickname,password,email,address)values('dfgloop',x,'[email protected]','china.js');
-> set x=x+1;
-> if x>=8 then
-> leave insertloop;
-> end if;
-> end loop;
-> end;
Query OK, 0 rows affected
호출 결과:mysql> call testloop();
Query OK, 1 row affected
mysql> select * from student;
+---------------+---------------+----------------------+-----------+----+
| nickname | password | email | address | id |
+---------------+---------------+----------------------+-----------+----+
| elgin | 12345 | [email protected] | xinbei9-2 | 1 |
| elgin | 12345 | [email protected] | xinbei9-2 | 2 |
| seth | 12345 | [email protected] | xinbei9-2 | 3 |
| 3344 | ddff3322 | [email protected] | xinbei9-2 | 4 |
| ddddfff | procedure1234 | [email protected] | xinbei9-2 | 5 |
| jdbcName | jdbc1234 | [email protected] | xinbei9-2 | 6 |
| testProcedure | procedure1234 | [email protected] | china.js | 7 |
| jdbcName | jdbc1234 | [email protected] | china.js | 9 |
| dfg | 5 | [email protected] | china.js | 10 |
| dfg | 6 | [email protected] | china.js | 11 |
| dfg | 7 | [email protected] | china.js | 12 |
| dfgloop | 5 | [email protected] | china.js | 13 |
| dfgloop | 6 | [email protected] | china.js | 14 |
| dfgloop | 7 | [email protected] | china.js | 15 |
+---------------+---------------+----------------------+-----------+----+
14 rows in set
4. 비정상 처리 Error Handling
예외 처리를 선언하는 구문:
DECLARE
{ EXIT | CONTINUE } HANDLER FOR
{ error-number | { SQLSTATE error-string } | condition } SQL statement
① CONTINUE 예외 처리 예:
상술한 학생표의 기초 위에서
저장 프로시저:
mysql> create procedure testhandler()
-> begin
-> declare CONTINUE HANDLER FOR SQLSTATE '23000' set @x2=3;
-> set @x=1;
-> insert into student(nickname,password,email,address,id)values('dfgloop','330335','[email protected]','china.js',15);
-> set @x=3;
-> end;
Query OK, 0 rows affected
호출 후 결과:mysql> call testhandler();
Query OK, 0 rows affected
mysql> select @x,@x2;
+----+-----+
| @x | @x2 |
+----+-----+
| 3 | 3 |
+----+-----+
1 row in set
프로세스 분석 수행:첫 번째 단계는 set @x=1을 실행합니다.다음에 insert 문장을 실행하려고 시도합니다. 키 충돌 오류 삽입 실패와 오류 처리 문장 set @x2=3을 실행한 다음 set @x=3 문장을 계속 실행합니다.
이를 통해 알 수 있듯이 CONTINUE 이상 처리로 인해 오류가 발생한 후에 오류 처리 문장을 실행한 후에 다음 문장을 계속 실행한다(본 예는 set@x=3).
② EXIT 예외 처리 예:
저장 프로시저:
mysql> create procedure testhandler1()
-> begin
-> declare EXIT HANDLER FOR SQLSTATE '23000' set @x2=3;
-> set @x=1;
-> insert into student(nickname,password,email,address,id)values('dfgloop','330335','[email protected]','china.js',15);
-> set @x=3;
-> end;
Query OK, 0 rows affected
호출 후 결과:mysql> call testhandler1();
Query OK, 0 rows affected
mysql> select @x,@x2;
+----+-----+
| @x | @x2 |
+----+-----+
| 1 | 3 |
+----+-----+
1 row in set
첫 번째 단계는 set @x=1을 실행합니다.다음에 insert 문장을 실행하려고 시도합니다. 키 충돌 오류가 발생하여 삽입에 실패하고 오류 처리 문장 set@x2=3을 실행하였으며, 오류가 발생하여 이번 실행을 종료하였습니다.
이를 통해 알 수 있듯이 EXIT 이상 처리이기 때문에 오류가 발생한 후에 오류 처리 문장을 집행하고 그 다음에 퇴출하며 후속 문장을 계속 집행하지 않는다.오유표
성명 커서
DECLARE cursor_nameCURSOR FORselect_statement
이 문장은 커서를 설명합니다.하위 프로그램에서 여러 개의 커서를 정의할 수도 있지만 블록의 모든 커서에는 유일한 이름이 있어야 합니다.
커서 열기
OPEN cursor_name
이 문장은 이전에 설명한 커서를 엽니다.
커서 FETCH
FETCH cursor_nameINTO var_name [, var_name]...
이 문장은 지정한 열기 커서로 다음 줄을 읽습니다. (다음 줄이 있다면)
그리고 전진 커서 포인터.
커서 CLOSE 닫기
CLOSE cursor_name
이 문장은 이전에 열린 커서를 닫습니다.
명시적으로 닫히지 않으면 선언된 복합 문 끝에서 커서가 닫힙니다.
커서 특성:
READ ONLY는 읽기 전용이며 값을 부여할 수 없는 값만 가져옵니다.
NOT SCROOLABLE은 롤백할 수 없으며 순차적으로 읽을 수 있습니다.
ASENSITIVE는 커서가 열린 테이블에서 업데이트 업무를 수행할 수 없습니다.
커서 사용 예:
mysql> create procedure testcur(out val int)
-> begin
-> declare a,b int;
-> declare cur1 cursor for select id from student;
-> declare continue handler for not found set b=1;
-> open cur1;
-> repeat fetch cur1 into a;
-> until b=1 end repeat;
-> close cur1;
-> set val=a;
-> end;
Query OK, 0 rows affected
호출 및 결과 보기:mysql> call testcur(@x);
Query OK, 0 rows affected
mysql> select @x;
+----+
| @x |
+----+
| 15 |
+----+
1 row in set
취약한 오류: 1328 - Incorrect number of FETCH variables이 오류에 사용된 스토리지 프로세스 문이 나타납니다.
mysql> create procedure testcur(out val int)
-> begin
-> declare a,b int;
-> declare cur1 cursor for select * from student;
-> declare continue handler for not found set b=1;
-> open cur1;
-> repeat fetch cur1 into a;
-> until b=1 end repeat;
-> close cur1;
-> set val=a;
-> end;
Query OK, 0 rows affected
위에서 정의한 커서의 문구에서 쿼리 문구를 사용할 때 select*, 즉 student 테이블에서 모든 기록을 쿼리하고fetch에서fetch cur1 into a는 쿼리 결과를 받는 변수가 a뿐이고 쿼리 결과는 5개의 필드가 있어서 위의 오류가 발생할 수 있습니다. Incorrect number of FETCH variables. 여러 개의 결과 값을 받으려면 쿼리 결과를 받는 변수를 추가할 수 있습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다: