2014-02-08 2 views
3

내 응용 프로그램은 고유 한 요청 ID를 응용 프로그램에 반환하는 저장 프로 시저를 통해 여러 MySQL 테이블의 모든 http 요청에 대한 세부 정보를 기록합니다.MySQL 저장 프로 시저 - 여러 행 삽입

CREATE TABLE `http_header` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
`request_id` INT(10) UNSIGNED NOT NULL, 
`name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
`value` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
PRIMARY KEY (`id`)) 

문제는 각 클라이언트가 다른 번호와 헤더의 유형을 가지고 있다는 것입니다 :

CALL http_req('ip', 'url', 'method', 'timestamp', @error, @request_id); 

지금 나는 또한 테이블, 별도의 행의 각 헤더에 모든 HTTP 요청 헤더를 기록합니다. 모든 헤더 세부 사항을 저장 프로 시저에 전달한 다음 위의 테이블에 삽입하는 방법을 찾지 못했습니다.

INSERT INTO http_header (request_id, name, value) 
    VALUES (20153, 'cache-control', 'max-age=0'), 
      (20153, 'accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'), 
      (20153, 'accept-encoding', 'gzip,deflate,sdch'); 

두 번째 쿼리를 저장하고 저장된 내부에서 헤더를 삽입 할 수 있습니다 :

현재 내가 헤더를 저장하기 위해 생성하고 저장 프로 시저를 호출 한 후 내 응용 프로그램에서 두 번째 삽입 쿼리를 실행해야 순서? 모든 헤더를 단일 문자열로 전달하고 저장 프로 시저 내부에서 구문 분석하는 것?

답변

0

예, 가능합니다. MySQL은 충분한 흐름 제어 구조 (REPEAT, IF)와 문자열 처리 (LOCATE(), SUBSTRING())를 지원하여 데이터베이스의 헤더 문자열을 분할 할 수 있습니다. 다음은 매우 단순한 예입니다.

CREATE PROCEDURE http_req(IN ip CHAR(12), IN url VARCHAR(512), IN method CHAR(8), IN ts DATETIME, IN headers TEXT, OUT err INT, OUT request_id INT) 
BEGIN 
DECLARE loc INT; 
DECLARE hloc INT; 
DECLARE hdr TEXT DEFAULT NULL; 
DECLARE hval TEXT DEFAULT NULL; 
DECLARE s TEXT DEFAULT NULL; 

START TRANSACTION; 

INSERT INTO http_requests VALUES (NULL,INET_ATON(ip), url, method, ts); 
SELECT last_insert_id() INTO request_id; 

REPEAT 
    SET loc=LOCATE("\n",headers); 

    IF (loc = 0) THEN 
    SET s=headers; 
    ELSE 
    SET s=SUBSTRING(headers,1,loc-1); 
    SET headers=SUBSTRING(headers,loc+1); 
    END IF; 

    SET hloc=LOCATE(':',s); 

    IF (hloc = 0) THEN 
    SET hdr=s; 
    SET hval=''; 
    ELSE 
    SET hdr=SUBSTRING(s,1,hloc-1); 
    SET hval=SUBSTRING(s,hloc+1); 
    END IF; 

    INSERT INTO http_header VALUES (null,request_id,hdr,hval); 

UNTIL (loc=0) END REPEAT; 

COMMIT; 

END 

이 코드에는 몇 가지 명백한 문제가 있습니다. 줄 바꿈 (\n)이 포함 된 경우 머리글과 같이 잘못 저장됩니다. 또한 오류 관리가 없습니다 (예 : err 반환 값이 올바르게 채워지지 않고 롤백되지 않음). 이 문제를 해결하려면 독자에게 연습 과제로 남겨 둡니다.)