在perl中创建我自己的DBI :: Iterator实现

时间:2013-05-07 02:52:26

标签: oracle perl dbi hp-ux

更新:

现在我正在尝试接收大约120M行的数组。原因我没有在UTL_file上执行此操作是因为在我们的生产服务器中,它需要oracle用户访问权限才能将写入的平面文件写入我们所需的目录。加入问题的是,提取后仍然需要进行大量的文本操作,我认为这是Perl的工作。

我现在要做的是编写自己的DBI :: Iterator实现以及它可能需要的所有其他依赖项;但要清楚,不一定都是。 (比如只有DBI的一些方法,然后只是idb_rows ...只是为了让它运行,因为我无法安装模块)

原始问题:

美好的一天, 我对perl编程比较陌生,一周前我开始在perl中再次收到内存不足的消息。我之前通过切换到64位perl来解决这个问题。

我昨天刚发现生产机器的内核不允许我使用超过4GB的内存(在我的其他生产服务器中,我能够将大量数据加载到内存中)

以下是我在生产服务器中的具体限制

  1. 我不允许安装perl的新模块
  2. 在某种程度上,我被允许在本地安装它们但我遇到了麻烦
  3. 我现在打算做的是重新创建这个模块。 Iterator::DBI

    我没有迭代器的背景。我通过下面的函数开发数据库提取和ETL过程的时间最长。这是我第一次在使用下面的功能一年半后再次遇到内存不足错误。

    sub myDBI
    {
        my ($filename) = @_; 
        my $query = "";
        unless(open(FILE,$filename))
        {
            Logger("[ ERR ] unable to open $SETTINGS{SQL_TRIGGER}\n");
            print
            die;
        }
        my @result=`sqlplus -S $SETTINGS{USER_NAME}/$SETTINGS{PASSWORD}\@$SETTINGS{DB_NAME} <<END
        SET HEADING OFF
        SET FEEDBACK OFF
        SET SERVEROUTPUT ON
        SET LINES 5000
        SET COLSEP "||"
        $query
        /
        `
        ;
        @result;
    }
    

1 个答案:

答案 0 :(得分:1)

您有几种选择:

  • 如果安装了local::lib,则可以将Iterator :: DBI等CPAN模块安装到用户目录中。您只需要设置一些环境变量来指定要使用的目录。

    export PERL_MB_OPT='--install_base /home/username/perl5'
    export PERL_MM_OPT='INSTALL_BASE=/home/username/perl5'
    export PERL5LIB='/home/username/perl5/lib/perl5/i386-linux:/home/username/perl5/lib/perl5'
    export PATH="/home/username/perl5/bin:$PATH"
    
  • 您实际上不需要Iterator :: DBI。该模块只是将一个Iterator对象包装在DBI语句句柄周围,该句柄本身就是一个迭代器。因此,您可以直接使用DBI连接到数据库。 (请注意,无论哪种方式,您都将直接连接到数据库,而不是通过sqlplus。)

    use DBI;
    my $dbh = DBI->connect(...);
    my $sth = $dbh->prepare($sql_query);
    $sth->execute(@params);
    # iterate
    while (my $row = $sth->fetchrow_arrayref) {
        ...
    }
    
  • 如果您真的想使用Iterator :: DBI并且无法安装模块,则可以直接复制source code并将其放在./Iterator/DBI.pm相对于您的应用程序中。但问题是你需要绕过依赖项。为此,我会使用简单的diecroak替换异常,并将Iterator替换为闭包(有关如何执行此操作,请参阅Higher Order Perl的第5章)。对于初学者Perl程序员来说,这个选项看起来很难。

  • 如果你真的无法让DBI正常工作,你可以将sqlplus输出传递给一个文件并遍历文件。