MySQL存储过程-插入多行

MySQL存储过程-插入多行,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,

我的应用程序通过一个存储过程将每个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,
`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
返回值填充不正确;没有回滚)。修复这些问题已留给读者作为练习;)