通过perl从表中获取所有记录

发布于 2025-01-11 15:29:02 字数 972 浏览 0 评论 0原文

我期望通过 Perl 从表中获取所有 5,812,750 条记录。目前,我遇到内存不足错误。读取所有记录的任何其他最佳替代方法。

sub sane {
    my $self = shift;

    my $dbh = DBI->connect(
       'dbi:Oracle:usbmfs',
       'US', 'states',
       { AutoCommit => 0, RaiseError => 1 }
    );

    my $sth = $dbh->prepare(qq{
        select cpu_id, system, generation, vendor, item,
               week_first_moved, week_last_moved
          from us_item_tbl
    });

    $sth->execute();

    my $rows = @{ $dbh->selectall_arrayref('
        select upc_id, system, generation, vendor, item,
               week_first_moved, eek_last_moved
          from uk_item_tbl
    ') };

    my %lookup;
    foreach my $row (@$rows) {
        my($cpu, sys, $gen, $vend, $item, $wad, $wlm) = @$rows;
        my $ean = sprintf "%02s%05s%05s", $sys, $vend, $item;
        $cpu = sprintf "%014s", $cpu;
        $lookup{$nae}{$cpu} = [$wad, $wlm];
    }       
}

I am expecting to fetch all 5,812,750 records from table through Perl. Currently, I am getting an out of memory error. Any other best alternative way to read all the records.

sub sane {
    my $self = shift;

    my $dbh = DBI->connect(
       'dbi:Oracle:usbmfs',
       'US', 'states',
       { AutoCommit => 0, RaiseError => 1 }
    );

    my $sth = $dbh->prepare(qq{
        select cpu_id, system, generation, vendor, item,
               week_first_moved, week_last_moved
          from us_item_tbl
    });

    $sth->execute();

    my $rows = @{ $dbh->selectall_arrayref('
        select upc_id, system, generation, vendor, item,
               week_first_moved, eek_last_moved
          from uk_item_tbl
    ') };

    my %lookup;
    foreach my $row (@$rows) {
        my($cpu, sys, $gen, $vend, $item, $wad, $wlm) = @$rows;
        my $ean = sprintf "%02s%05s%05s", $sys, $vend, $item;
        $cpu = sprintf "%014s", $cpu;
        $lookup{$nae}{$cpu} = [$wad, $wlm];
    }       
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最美的太阳 2025-01-18 15:29:02

我认为使用 selectall_arrayref 是出现内存不足错误的原因。请尝试使用以下代码。

我将 DBI->connect() 调用更改为使用 RowCacheSize 设置为较小的值 (20),将 selectall_arrayref 更改为使用 prepare() /execute() 相反,并迭代两个查询结果,一次仅获取一行。另外,我修复了代码中的几个拼写错误:$sys 缺少美元符号,写为 $ean 而不是 $nae,更改查询中的“upc_id”改为“cpu_id”,并修复了“eek_last_moved”的拼写。

while条件中的//定义的or运算符< /a>,而不是 m// 正则表达式运算符。 // 当左侧参数为 undef 时计算其右侧参数。 fetchrow_arrayref当返回的行数用完时,返回 undef ;发生这种情况时,会对第二个查询结果调用 fetchrow_arrayref 并将结果放入 $row 中。如果 Perl 抱怨 //(可能是因为您的 Perl 早于 5.10),请尝试使用 || 代替。

sub sane {
    my $self = shift;

    my $dbh = DBI->connect(
       'dbi:Oracle:usbmfs',
       'US', 'states',
       { AutoCommit => 0, RaiseError => 1, RowCacheSize => 20 }
    );

    my $sth = $dbh->prepare(qq{
        select cpu_id, system, generation, vendor, item,
               week_first_moved, week_last_moved
          from us_item_tbl
    });

    $sth->execute();

    my $sth2 = $dbh->prepare('
        select cpu_id, system, generation, vendor, item,
               week_first_moved, week_last_moved
          from uk_item_tbl
    ');

    $sth2->execute();

    my %lookup;
    while (my $row = $sth->fetchrow_arrayref() // $sth2->fetchrow_arrayref()) {
        my($cpu, $sys, $gen, $vend, $item, $wad, $wlm) = @$row;
        my $ean = sprintf "%02s%05s%05s", $sys, $vend, $item;
        $cpu = sprintf "%014s", $cpu;
        $lookup{$ean}{$cpu} = [$wad, $wlm];
    }
}

I think using selectall_arrayref is why you get Out of Memory error. Try the following code instead.

I changed DBI->connect() invocation to use RowCacheSize set to a smallish value (20), changed selectall_arrayref to use prepare()/execute() instead, and iterates through both query results only fetching one row at a time. Also, I fixed a couple of typos in your code: $sys was missing the dollar sign, wrote $ean instead of $nae, changed "upc_id" to "cpu_id" in the query, and fixed the spelling of "eek_last_moved".

The // in the while condition is the defined or operator, not the m// regex operator. // evaluates its right argument when the left one is undef. fetchrow_arrayref returns undef when it runs out of rows to return; when this happens, fetchrow_arrayref is called on the second query result and the result is put in $row. If Perl complains about the // (probably because you have a perl earlier than 5.10), try using || instead.

sub sane {
    my $self = shift;

    my $dbh = DBI->connect(
       'dbi:Oracle:usbmfs',
       'US', 'states',
       { AutoCommit => 0, RaiseError => 1, RowCacheSize => 20 }
    );

    my $sth = $dbh->prepare(qq{
        select cpu_id, system, generation, vendor, item,
               week_first_moved, week_last_moved
          from us_item_tbl
    });

    $sth->execute();

    my $sth2 = $dbh->prepare('
        select cpu_id, system, generation, vendor, item,
               week_first_moved, week_last_moved
          from uk_item_tbl
    ');

    $sth2->execute();

    my %lookup;
    while (my $row = $sth->fetchrow_arrayref() // $sth2->fetchrow_arrayref()) {
        my($cpu, $sys, $gen, $vend, $item, $wad, $wlm) = @$row;
        my $ean = sprintf "%02s%05s%05s", $sys, $vend, $item;
        $cpu = sprintf "%014s", $cpu;
        $lookup{$ean}{$cpu} = [$wad, $wlm];
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文