求助:如何通过Perl+CGI实现多组结构化数据批量存入MySQL
问题需求
需要通过HTML的textarea一次性提交多组以---START----和---END---标记包裹的结构化数据(每组包含FULLNAME、BINF、PRICE、COUNTRY字段),实现批量入库而非逐条插入数据库。现有Perl+CGI代码框架,但缺少数据提取与批量入库的逻辑,需补充实现。
示例提交数据
---START---- |FULLNAME: JANE DEO |BINF : 492BBJJ |PRICE: 10 |COUNTRY: GR ---END--- ---START---- |FULLNAME: JOHN DEO |BINF : K92BBJJ |PRICE: 24 |COUNTRY: AS ---END---
现有Perl+CGI代码框架
#!/usr/bin/perl -w use DBI; use CGI qw/:standard/; my $CGI = CGI->new; my $host = "localhost"; my $dbname = ""; my $usr = ""; my $pwd = ''; my $dbh_usr = DBI->connect("DBI:mysql:$dbname:$host", $usr, $pwd, {RaiseError => 1,}) or die $DBI::errstr; # $binf extracted from data where is |BINF : # $price extracted from data where is |PRICE: # $info this is the whole ---START---- and ---END--- my $upload = $CGI->param("data"); if ($upload) { my $update_info = $dbh_usr->prepare("INSERT INTO ITEMS(user, pid, basnm, binf, info, status, price) VALUES(?,?,?,?,?,?,?)"); $update_info->execute('join123', '898', 'iono', $binf, $info, 'Active', $price); $update_info->finish; } $dbh_usr->commit; $dbh_usr->disconnect; print "Content-type: text/html\n\n"; print <<HTML; <!DOCTYPE html> <html> <head> </head> <body> <h1>The textarea</h1> <form method="POST"> <textarea name="data" rows="4" cols="50"></textarea> <br> <input type="submit" value="Submit"> </form> </body> </html> HTML
解决方案与代码修改
核心逻辑步骤
- 分割多组数据:通过正则匹配
---START----和---END---,提取每组完整的内容块 - 解析单组字段:对每组内容,用正则提取BINF、PRICE等目标字段值
- 批量插入数据库:循环处理每组数据,调用预编译的SQL语句完成插入
修改后的完整代码
#!/usr/bin/perl -w use strict; # 开启严格模式,减少语法错误 use DBI; use CGI qw/:standard/; my $CGI = CGI->new; my $host = "localhost"; my $dbname = ""; # 填写实际数据库名 my $usr = ""; # 填写实际用户名 my $pwd = ''; # 填写实际密码 my $dbh_usr = DBI->connect("DBI:mysql:$dbname:$host", $usr, $pwd, { RaiseError => 1, AutoCommit => 0, # 关闭自动提交,批量操作后统一提交 }) or die $DBI::errstr; my $upload = $CGI->param("data"); if ($upload) { # 预编译插入SQL,复用提升效率 my $insert_stmt = $dbh_usr->prepare("INSERT INTO ITEMS(user, pid, basnm, binf, info, status, price) VALUES(?,?,?,?,?,?,?)"); # 匹配所有数据组:提取---START----和---END---之间的内容 while ($upload =~ /---START----(.*?)---END---/gs) { my $info = $1; # 保存当前组的完整内容 my ($binf, $price); # 解析BINF字段,去除首尾空格 if ($info =~ /\|BINF\s*:\s*(.+)/) { $binf = $1; $binf =~ s/^\s+|\s+$//g; } # 解析PRICE字段,去除首尾空格 if ($info =~ /\|PRICE\s*:\s*(.+)/) { $price = $1; $price =~ s/^\s+|\s+$//g; } # 仅当必要字段存在时执行插入,避免无效数据 if ($binf && $price) { $insert_stmt->execute('join123', '898', 'iono', $binf, $info, 'Active', $price); } } $insert_stmt->finish; $dbh_usr->commit; # 统一提交所有插入操作 } else { $dbh_usr->rollback; # 无数据时回滚空事务 } $dbh_usr->disconnect; print "Content-type: text/html\n\n"; print <<HTML; <!DOCTYPE html> <html> <head> </head> <body> <h1>The textarea</h1> <form method="POST"> <textarea name="data" rows="15" cols="60"></textarea> <br> <input type="submit" value="Submit"> </form> </body> </html> HTML
关键说明
- 添加
use strict严格模式,强制规范代码写法,减少潜在bug - 关闭
AutoCommit改为批量提交,提升数据库操作效率 - 使用正则
/---START----(.*?)---END---/gs匹配所有数据组,s修饰符让.匹配换行符,g修饰符实现全局匹配 - 对字段值做首尾空格清理,避免无效数据入库
- 增加字段存在性判断,防止因字段缺失导致插入失败
内容的提问来源于stack exchange,提问作者stevo JFK
相关产品推荐
相关产品推荐

