2

我需要从数据库记录中生成一个 XML 文件,并且出现“内存不足”错误。这是我正在使用的脚本,它是在谷歌上找到的,但它不适合我,而且它也在杀死服务器分配的内存。虽然这是一个开始。

#!/usr/bin/perl

use warnings;
use strict;
use XML::Simple;
use DBI;

my $dbh = DBI->connect('DBI:mysql:db_name;host=host_address','db_user','db_pass')
  or die DBI->errstr;

# Get an array of hashes
my $recs = $dbh->selectall_arrayref('SELECT * FROM my_table',{ Columns => {} });

# Convert to XML where each hash element becomes an XML element
my $xml = XMLout( {record => $recs}, NoAttr => 1 );

print $xml;

$dbh->disconnect;

该脚本仅打印记录,因为我使用 where 子句对单个行 id 进行了测试。

  • 首先,我无法将输出保存到file.xml。

  • 其次,我需要以某种方式将“作业”拆分为多个作业,然后将 XML 文件全部放在一起。

我不知道如何实现两者。

约束:无权更改服务器设置。

4

2 回答 2

4

这些是问题线:

my $recs = $dbh->selectall_arrayref('SELECT * FROM my_table',{ Columns => {} });

这会将整个表读入内存,将每一行表示为一个值数组。

my $xml = XMLout( {record => $recs}, NoAttr => 1 );

这可能是更大的结构,它是一个完整的 XML 字符串。

最低内存使用解决方案需要涉及一次加载表一项,并立即打印该项目。在 DBI 中,可以进行查询,以便在循环中一次获取一行。

You will need to play with this before the result looks like your intended output (I haven't tried to match your XML::Simple output - I'm leaving that to you:

print "<records>\n";

my $sth = $dbh->prepare('SELECT * FROM my_table');
$sth->execute;

while ( my $row = $sth->fetchrow_arrayref ) {
  # Convert db row to XML row
  print XMLout( {row => $row}, NoAttr => 1 ),"\n";
}

print "</records>\n";

Perl can use e.g. open( FILEHANDLE, mode, filename ) to start access to a file and print FILEHANDLE $string to print to it, or you could just call your script and pipe it to a file e.g. perl myscript.pl > table.xml

于 2013-03-30T07:51:04.033 回答
0

没有约束的 select * 会扼杀你的记忆。为您的查询添加一些约束,即日期或 ID,并使用循环执行查询并分块执行输出。这样你就不需要在开始输出之前将整个表加载到 mem 中。

于 2013-03-30T00:33:19.563 回答