저장 프로세스 문법

1. 저장 프로세스의 변수
① 변수에 대한 설명:
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. 여러 개의 결과 값을 받으려면 쿼리 결과를 받는 변수를 추가할 수 있습니다.

좋은 웹페이지 즐겨찾기