MySQL存储过程-插入多行
我的应用程序通过一个存储过程将每个http请求的详细信息记录在几个MySQL表中,该存储过程向应用程序返回一个唯一的请求idMySQL存储过程-插入多行,mysql,stored-procedures,rows,Mysql,Stored Procedures,Rows,我的应用程序通过一个存储过程将每个http请求的详细信息记录在几个MySQL表中,该存储过程向应用程序返回一个唯一的请求id CALL http_req('ip', 'url', 'method', 'timestamp', @error, @request_id); 现在,我还想将所有http请求头记录到一个表中,每个头位于一个单独的行中: CREATE TABLE `http_header` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
CALL http_req('ip', 'url', 'method', 'timestamp', @error, @request_id);
现在,我还想将所有http请求头记录到一个表中,每个头位于一个单独的行中:
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`))
问题在于,每个客户端都有不同数量和类型的头。我还没有找到一种方法将所有的头细节传递给存储过程,然后将它们插入上表
当前,我必须在存储过程调用后从应用程序生成并执行第二个insert查询以保存标题:
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');
是否可以保存第二个查询并从存储过程中插入头?就像将所有头作为单个字符串传递并在存储过程中解析一样?是的,这是可能的。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
返回值填充不正确;没有回滚)。修复这些问题已留给读者作为练习;)