perl — помогите переработать код, чтобы включить использование подпрограммы

Мой тестовый сценарий просто устанавливает соединение perl dbi с базой данных mysql и, учитывая список таблиц, извлекает (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: $!";
    };

person cjd143SD    schedule 25.02.2011    source источник


Ответы (2)


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: $!";
};

Если вам действительно не нужно подключаться к базе данных для каждого выполняемого оператора, держите базу данных открытой между операциями.

person Jonathan Leffler    schedule 25.02.2011
comment
правильно, мне не нужно подключаться каждый раз для каждой таблицы. одно постоянное соединение — это все, что нужно для извлечения информации. благодаря. - person cjd143SD; 25.02.2011
comment
@ cjd143SD: вы, вероятно, обнаружите, что в DBI есть метод для прямого получения списка имен таблиц, который позволяет избежать операции qx(): my @tables = $dbh->tables;? - person Jonathan Leffler; 25.02.2011
comment
не уверен, почему я получаю сообщение об ошибке fetchrow_array failed. DBD::mysql::st выполнить не удалось: у вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с «1 limit 1». Я думаю, что sql в порядке. Это работало раньше. - person cjd143SD; 25.02.2011
comment
@ cjd143SD: я думаю, chomp нас обманывает - контекст вызова функции предоставляет ему список-контекст вместо скалярного контекста. Я обновлю... - person Jonathan Leffler; 26.02.2011

Вместо создания собственного create_file вы можете использовать write_file из File::Slurp. Он абстрагируется от открытия/закрытия/умирания/печати.

person toolic    schedule 25.02.2011