perl - 帮助修改代码以包含子例程的使用

Posted

技术标签:

【中文标题】perl - 帮助修改代码以包含子例程的使用【英文标题】:perl - help reworking code to include use of a sub routine 【发布时间】:2011-07-04 12:45:22 【问题描述】:

我的测试脚本只是简单地与 mysql 数据库建立 perl dbi 连接,并给出一个表列表,然后为每个表提取 (1) 条记录。

对于我列出的每个表,我还想将 (1) 记录打印到它自己的文件中。例如,如果我有一个包含 100 个表的列表,我应该期望 100 个唯一文件,每个文件都有 (1) 个记录。

到目前为止,代码可以正常工作,但我有兴趣创建一个子例程,将其称为 create_file 以获取处理 #Create file 的代码片段

我不熟悉编写子例程,如果可能的话,我需要帮助来实现它。 我不确定如何调用构建数据的部分。 $data='';

有人可以告诉我这样做的好方法吗?感谢您的帮助。

代码:

# Get list of tables
my @tblist = qx(mysql -u foo-bar -ppassw0rd --database $dbsrc -h $node --port 3306 -ss -e "show tables");

# Data output
    foreach my $tblist (@tblist)
    
       my $data = '';
       chomp $tblist;

       #Create file
       my $out_file = "/home/$node-$tblist.$dt.dat";
       open (my $out_fh, '>', $out_file) or die "cannot create $out_file: $!";

       my $dbh = DBI->connect("DBI:mysql:database=$dbsrc;host=$node;port=3306",'foo-bar','passw0rd');
       my $sth = $dbh->prepare("SELECT UUID(), '$node', ab, cd, ef, gh, hi FROM $tblist limit 1");
       $sth->execute();
             while (my($id, $nd,$ab,$cd,$ef,$gh,$hi) = $sth->fetchrow_array() ) 
             $data = $data. "__pk__^A$id^E1^A$nd^E2^A$ab^E3^A$cd^E4^A$ef^E5^A$gh^E6^A$hi^E7^D";
             
             $sth->finish;
             $dbh->disconnect;

       #Create file
       print $out_fh $data;
       close $out_fh or die "Failed to close file: $!";
    ;

【问题讨论】:

【参考方案1】:
my $dt = "2011-02-25";
my $dbsrc = "...";
my $node = "...";

# Get list of tables
my @tblist = qx(mysql -u foo-bar -ppassw0rd --database $dbsrc -h $node --port 3306 -ss -e "show tables");
my $dbh = DBI->connect("DBI:mysql:database=$dbsrc;host=$node;port=3306",'foo-bar','passw0rd');
foreach my $tblist (@tblist)

   # This breaks - chomp is given a list-context
   #extract_data($dbh, chomp($tblist));
   chomp $tblist;
   extract_data($dbh, $tblist);
;
$dbh->disconnect;

sub extract_table

     my($dbh, $tblist) = @_;

     my $out_file = "/home/$node-$tblist.$dt.dat";
     open (my $out_fh, '>', $out_file) or die "cannot create $out_file: $!";

     my $sth = $dbh->prepare("SELECT UUID(), '$node', ab, cd, ef, gh, hi FROM $tblist limit 1");
     $sth->execute();
     while (my($id, $nd,$ab,$cd,$ef,$gh,$hi) = $sth->fetchrow_array() ) 
         print $out_fh "__pk__^A$id^E1^A$nd^E2^A$ab^E3^A$cd^E4^A$ef^E5^A$gh^E6^A$hi^E7^D";
     
     $sth->finish;

     close $out_fh or die "Failed to close file: $!";
;

除非您确实需要为您执行的每条语句连接到数据库,否则请在操作之间保持数据库打开。

【讨论】:

对,我不需要每次都连接每个 tbl。一个持久连接就是提取信息所需的全部 id。谢谢。 @cjd143SD:你可能会发现DBI中有一种方法可以直接获取表名列表,这样可以避免qx()操作:my @tables = $dbh->tables;? 不确定为什么我在 fetchrow_array 上收到错误失败。 DBD::mysql::st 执行失败:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以了解在 '1 limit 1' 附近使用的正确语法。我认为sql很好。它以前工作过。 @cjd143SD:我猜chomp 搞砸了我们——函数调用上下文为它提供了列表上下文而不是标量上下文。我会更新...【参考方案2】:

您可以使用来自File::Slurp 的write_file,而不是创建自己的create_file。 它抽象出打开/关闭/模具/打印。

【讨论】:

以上是关于perl - 帮助修改代码以包含子例程的使用的主要内容,如果未能解决你的问题,请参考以下文章

Perl 中左值子例程的用途是啥?

无法通过从两个不同子例程传递给新子例程的值来执行计算:Perl

模块化程序-子例程

如何修改这个 Perl 子例程,以便它使用 print_file 打印文件的内容?

九十SAP中ALV事件之四,事件子例程的参数

如何在Perl子例程中使用$ a和$ b