MySQL 저장 프로 세 스 학습 실천
7682 단어 Mysql 저장 프로시저
Mysql 은 5.0 부터 저장 과정 과 trigger 를 지원 하기 시 작 했 습 니 다. my sql 을 좋아 하 는 친구 들 에 게 my sql 을 더 좋아 하 는 이 유 를 주 었 습 니 다. 문법 적 으로 PL / SQL 과 차이 가 있 지만 프로 그래 밍 을 한 사람 은 문법 이 문제 가 아니 라 사상 이라는 것 을 알 고 있 습 니 다. 문법 을 대체적으로 이해 한 후에 변수 정의, 순환, 판단, 커서, 이상 처리 등 몇 가지 측면 에서 상세 하 게 배 웠 습 니 다.커서 사용법 Mysql 은 아직 특별 합 니 다. PL / SQL 만큼 사용 하기 쉽 지 는 않 지만, 대체로 커서 declare fetchSeqCursor cursor for select seqname, value from sys 를 정의 합 니 다.sequence;커서 open fetchSeqCursor 사용 하기;fetch 데이터 fetch cursor intoseqname, _value;커서 close fetchSeqCursor 닫 기;그러나 이것 은 모두 cursor 를 대상 으로 하 는 조작 일 뿐 입 니 다. PL / SQL 과 다 를 것 이 없습니다. 그러나 이것 만 으로 는 Mysql 의 fetch 과정 을 작성 할 수 없고 다른 깊이 있 는 지식 도 알 아야 좋 은 커서 를 사용 하 는 procedure 를 진정 으로 쓸 수 있 습 니 다.
우선 fetch 는 순환 문 구 를 떠 날 수 없습니다. 그러면 순환 문 구 를 먼저 알 아 보 세 요.나 는 보통 Loop 과 while 를 사용 하 는 것 이 비교적 명확 하고 코드 가 간단 하 다 고 생각한다.여기에 Loop 을 예 로 들 면 fetchSeqLoop: Loopfetch cursor intoseqname, _value;
end Loop;현재 데 드 사이클 입 니 다. 종료 조건 이 없습니다. 여기 서 Oacle 과 차이 가 있 습 니 다. Oracle 의 PL / SQL 지침 에는 내 현적 변수% notfound 가 있 습 니 다. Mysql 은 Error handler 의 성명 을 통 해 판단 합 니 다. declare continue handler for Not found (do some action).Mysql 에서 커서 가 넘 칠 때 미리 정 의 된 NOT FOUND 의 Error 가 발생 합 니 다. 우 리 는 이 Error 를 처리 하고 continue 의 handler 를 정의 하면 싱가포르 를 만 들 수 있 습 니 다. Mysql Error handler 는 Mysql 매 뉴 얼 을 조회 하여 flag 를 정의 할 수 있 습 니 다. NOT FOUND 에서 Flag 를 표시 하고 Loop 에서 이 flag 를 순환 을 끝 내 는 판단 으로 싱가포르 를 만 들 수 있 습 니 다.declare fetchSeqOk boolean; ## define the flag for loop judgementdeclare _seqname varchar(50); ## define the varient for store the datadeclare _value bigint(20);declare fetchSeqCursor cursor for select seqname, value from sys_sequence;## define the cursordeclare continue handler for NOT FOUND set fetchSeqOk = true; ## define the continue handler for not found flagset fetchSeqOk = false;
open fetchSeqCursor;fetchSeqLoop:Loopif fetchSeqOk thenleave fetchSeqLoop;elsefetch cursor into _seqname, _value;
select _seqname, _value;end if;
end Loop;close fetchSeqCursor;
이것 이 바로 완전한 과정 싱가포르 입 니 다. 그러면 생각 하 는 사람들 은 보통 여기 서 생각 합 니 다. 만약 에 그렇다면 포 함 된 커서 순환 싱가포르 를 어떻게 하 는 지 여 기 는 statement block 의 scope 에 따라 싱가포르 를 실현 할 수 있 습 니 다. Mysql 에서 begin end 를 통 해 statement block 을 나 눌 수 있 습 니 다. block 에서 정 의 된 변수 범위 도 이 block 에 있 습 니 다.따라서 끼 워 넣 은 커서 순환 에 대해 서 는 begin end 를 하나 더 추가 하여 그들 이 대응 하 는 error handler 를 구분 할 수 있 습 니 다.begin end 에서 이 커서 의 NOT FOUND handler 를 정의 합 니 다.
declare fetchSeqOk boolean; ## define the flag for loop judgementdeclare _seqname varchar(50); ## define the varient for store the datadeclare _value bigint(20);declare fetchSeqCursor cursor for select seqname, value from sys_sequence;## define the cursordeclare continue handler for NOT FOUND set fetchSeqOk = true; ## define the continue handler for not found flagset fetchSeqOk = false;
open fetchSeqCursor;fetchSeqLoop:Loopif fetchSeqOk thenleave fetchSeqLoop;elsefetch cursor into _seqname, _value; begin
declare fetchSeqOk boolean default 'inner';declare cursor2 cursor for select .... from ...;## define the cursordeclare continue handler for NOT FOUND set fetchSeqOk = true; ## define the continue handler for not set fetchSeqOk = false; open cursor2;fetchloop2 loopif fetchSeqOk thenelse
end if;
end loop;close cursor2;end;end if;
end Loop;close fetchSeqCursor;
이렇게 하면 더 많은 차원 의 순환 을 쉽게 실현 할 수 있 습 니 다. 그러나 Oacle 의 PL / SQL 에 비해 Mysql 은 아직 동적 커서 의 정 의 를 지원 하지 않 기 때문에 강력 한 동적 으로 SQL 을 조합 하여 커서 에서 할 수 없습니다. 그러나 이것 은 제 가 Mysql 에 대한 사랑 정도 에 전혀 영향 을 주지 않 습 니 다. 그녀 는 수 줍 은 연꽃 처럼 찬란 한 색채 가 없 지만 심 플 한 톤 이 라 고 생각 합 니 다.맑 고 납 먼지 하나 묻 지 않 은 고아 함 처럼 수많은 my sql 팬 들 을 끌 어 들 이 고 있 습 니까? 마치 하늘 을 잇 는 연잎 이 끝 없 이 푸 르 고 영일 연꽃 이 다른 빨간색 입 니 다.
첨부: Mysql 도 Oracle 의 execute immediate 와 유사 한 동적 SQL 기능 이 있 습 니 다. 이 기능 을 통 해 동적 커서 의 부족 한 점 을 얼마나 보완 할 수 있 습 니까? 싱가포르 set @ sqlStr = 'select * from table where condition 1 =?'prepare s1 for @sqlStr;execute s1 using @condition1; 만약 여러 개의 인자 가 쉼표 로 deallocate prepare s1 을 구분한다 면;수 동 으로 풀 거나 connection 이 닫 혔 을 때 server 는 자동 으로 회수 합 니 다.
다음은 제 가 쓴 비교적 복잡 한 데이터 베 이 스 를 뛰 어 넘 는 저장 과정 을 보 여 드 리 겠 습 니 다. 실 현 된 업 무 는 더 이상 말 하지 않 고 코드 를 보 겠 습 니 다.
주로 공 부 했 습 니 다: http://dev.mysql.com/doc/refman/5.1/zh/stored-procedures.html
DROP PROCEDURE IF EXISTS p1;
CREATE PROCEDURE p1()
BEGIN
DECLARE userIdVarchar1 VARCHAR(255);
DECLARE userIdInt1 INTEGER;
DECLARE fetchFlag1 TINYINT DEFAULT 1;
DECLARE cursor1 CURSOR FOR SELECT fqt.users.userId FROM fqt.users WHERE classId<>'' LIMIT 10;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchFlag1=0;
OPEN cursor1;
cursor1Loop:LOOP
IF fetchFlag1=0 THEN LEAVE cursor1Loop;
ELSE
FETCH cursor1 INTO userIdVarchar1;
SELECT jchome.jchome_member.uid INTO userIdInt1 FROM jchome.jchome_member WHERE jchome.jchome_member.username=userIdVarchar1;
BEGIN
DECLARE userIdVarchar2 VARCHAR(255);
DECLARE userIdInt2 INTEGER;
DECLARE fetchFlag2 TINYINT DEFAULT 1;
DECLARE statusFlag VARCHAR(30) DEFAULT 'OK';
DECLARE cursor2 CURSOR FOR SELECT fqt.users.userId FROM fqt.users WHERE fqt.users.classId =(SELECT u.classId FROM fqt.users AS u WHERE u.userId=userIdVarchar1) AND fqt.users.userId<>userIdVarchar1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchFlag2=0;
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET statusFlag='Duplicate Entry';
OPEN cursor2;
cursor2Loop:LOOP
IF fetchFlag2=0 THEN LEAVE cursor2Loop;
ELSE
FETCH cursor2 INTO userIdVarchar2;
SELECT jchome.jchome_member.uid INTO userIdInt2 FROM jchome.jchome_member WHERE jchome.jchome_member.username=userIdVarchar2;
IF userIdInt2 IS NULL THEN LEAVE cursor2Loop;
ELSE
IF statusFlag<>'Duplicate Entry' THEN
SET statusFlag='OK';
INSERT INTO jchome.jchome_friend(uid,fuid,fusername,status,gid,note,num,dateline) VALUES (userIdInt1,userIdInt2,userIdVarchar2,1,6,'test',0,0);
SELECT userIdInt1,userIdInt2,userIdVarchar2;
ELSE
SELECT 'Duplicate Entry';
END IF;
END IF;
END IF;
END LOOP;
CLOSE cursor2;
END;
END IF;
END LOOP;
CLOSE cursor1;
END;
CALL p1();
잘못된 DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' 에 대해
참고: http://dev.mysql.com/doc/refman/5.1/zh/error-handling.html
부록 B: 오류 코드 와 메시지
중간 에 캐 스 트 함수 로 varchar 를 mediumint 로 바 꾸 려 고 했 는데 결과 가 틀 렸 습 니 다. 나중에 보 니 http://dev.mysql.com/doc/refman/5.1/zh/functions.html#cast-functions
CAST(expr AS type), CONVERT(expr,type) , CONVERT(expr USING transcoding_name)
CAST() CONVERT () 함 수 는 한 유형의 값 을 가 져 오고 다른 유형의 값 을 만 드 는 데 사용 할 수 있 습 니 다.
이 종류 다음 값 중 하나 일 수 있 습 니 다:
BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MySQL 저장 프로 세 스 인 코딩 문제 해결1.MySQL 저장 프로 세 스 를 사용 하고 MySQL 은 utf 8 인 코딩 을 사용 하여 자바 배경 에서 SQL 구문 코드 를 실행 합 니 다. 이상 이 나타나다 이것 은 데이터베이스 인 코딩 문제 입 니 다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.