Скрипт взаимодействия с MySQL через модуль DBI

Вопросы и обсуждения, касающиеся программирования на Perl.
Ответить
Аватара пользователя
ZEN
Администратор
Сообщения: 1350
Зарегистрирован: 27 сен 2012, 18:23
Темы: 206
Откуда: Украина, Одесса
Статус: Не в сети

Скрипт взаимодействия с MySQL через модуль DBI

Сообщение ZEN » 12 авг 2013, 14:29

[spoiler="Подробное описание задания"]Написать программу, которая единственным своим аргументом принимает имя файла, в котором находятся простые SQL запросы 6(CREATE/SELECT/DELETE/UPDATE/INSERT/..), которые нужно выполнить один за одним.
Входные данные:
В первых 5-ти строках файла указаны параметры подключения к базе данных:
1. Hostname
2. Port
3. Database name
4. User name
5. Password

Дальше следуют блоки описывающие SQL запросы, они могут быть двух видов, первый описывает прoсотой запрос, без параметров:
-- sql
SELECT * FROM table1
-- end
и запрос с параметрами:
-- sql
UPDATE table1
SET column1 = ?
WHERE column2 = ?
-- param
value1,value2
-- end

Параметры разделены между собой запятыми и не могут содержать запятые внутри себя.

Выходные данные:
Результаты выполнения SELECT запросов, колонки разделённые знаком: |
В случае ошибки программа должна на STDERR выводить саму ошибку, а на STDOUT - 0.

Пример:
Входные данные:

localhost
3306
students
student
password

-- sql
drop table if exists `user`
-- end

-- sql
create table `user` (
id int unsigned not null auto_increment primary key,
name varchar(255) not null default ''
) charset='utf8' engine=myisam
-- end

-- sql
insert into `user`
(name)
values
(?)
-- param
alex
oleksii
igor
michael
nina
sewa
stas
vasyl
-- end

-- sql
update `user`
set name = ?
where name = ?
-- param
cono,oleksii
-- end

-- sql
select * from `user`
-- end

Выходные данные:
% ./dbi.pl dat/01_example.dat
1|alex
2|cono
3|igor
4|michael
5|nina
6|sewa
7|stas
8|vasyl

Примечание:
Обязательные DBI методы для использования: connect, prepare, do, disconnect[/spoiler]

Код: Выделить всё

#!/usr/bin/perl

use warnings;
use DBI;

# use first argument of script as file name whith data
my $test_file_path = $ARGV[0];
# open file and get file handler or die
open( FH, "<", "$test_file_path") or die ("Can not open test file: $!");

my @param_name = ("host", "port", "dbname", "username", "password");
my %hash;
my $sql = "";
my @params;
my $trigger = "";
# Load config values
while (<FH>) {
    chomp;
    $hash{$param_name[$.-1]} = $_ if ($param_name[$.-1]);
    last if (!defined $param_name[$.-1]);
}
# Connect to MySQL Sever DBI:mysql:databasename;host=db.example.com'
my $cfg = 'DBI:mysql:'.$hash{"dbname"}.';host='.$hash{"host"}.':'.$hash{"port"};
my $dbh = DBI->connect($cfg, $hash{"username"}, $hash{"password"}, { RaiseError => 0, PrintError => 0 });
if (!defined $dbh) {
    print "0\n";
    warn("Cannot connect to database $!");
    exit 2;
}
# Progress ...
while (<FH>) {
    chomp;
    $trigger = $_ and next if ($_ =~ m/^-- (.*)/);
    if ($trigger eq "-- sql") {
        $sql .= $_." ";
    } elsif ($trigger eq "-- param") {
        push(@params, $_);
    } elsif ($trigger eq "-- end") {
        # Execute SQL
        if ($sql =~ m/^(select|drop|create).*/i) {
            my $sth = $dbh->prepare(qq{$sql});
            $sth->execute();
            while (my @row = $sth->fetchrow_array()) {
                $" = '|';
                $tmp = "@row";
                print "$tmp\n";
            }
            $sth->finish();
        } else {
            foreach my $values(@params) {
                $dbh->do(qq{$sql}, undef, split(/,/, $values));
            }
        }
        # Clean values
        $sql = "";
        @params = split(/,/, "");
        $trigger = "";
    } else {
        print "0\n";
        warn("Unknow values");
        exit 3;
    } 
}

$dbh->disconnect();
close(FH);

exit 0;
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей