SQL * Plus внутри скрипта Perl - PullRequest
       19

SQL * Plus внутри скрипта Perl

5 голосов
/ 13 ноября 2009

Я пытаюсь подключиться к таблице с помощью SQL * Plus , извлечь данные в сценарии Perl и сохранить эти выходные данные в переменной Perl.

В сценарии оболочки я бы сделал это:

    SQL_RESULT=`sqlplus -s ${CONNECT_STRING} << EOF
    ${SQLPLUS_SETTINGS}
    select foo||'|'||bar ||'|'|| xyz from temp where dfg='some';
    exit;
    EOF`

Но как я могу сделать это в Perl?

Ответы [ 4 ]

10 голосов
/ 13 ноября 2009

Проверьте модуль DBI. Фактически, есть целый сайт, посвященный этому: dbi.perl.org . Также проверьте ссылку на модуль CPAN для DBI .

Вот пример кода, прямо из первого руководства по DBI в Google :

    use DBI;

    my $dbh = DBI->connect('DBI:Oracle:payroll')
        or die "Couldn't connect to database: " . DBI->errstr;
    my $sth = $dbh->prepare('SELECT * FROM people WHERE lastname = ?')
        or die "Couldn't prepare statement: " . $dbh->errstr;

    $sth->execute($lastname)             # Execute the query
        or die "Couldn't execute statement: " . $sth->errstr;

    # Read the matching records and print them out          
    while (@data = $sth->fetchrow_array()) {
        my $firstname = $data[1];
        my $id = $data[2];
        print "\t$id: $firstname $lastname\n";
    }
    if ($sth->rows == 0) {
      print "No names matched `$lastname'.\n\n";
    }
    $sth->finish;
    print "\n";
    print "Enter name> ";

    $dbh->disconnect;

Perl также имеет многострочный комментарий в стиле EOF; Вы можете сделать длинный запрос, как это:

my $query = <<'END_QUERY';
${SQLPLUS_SETTINGS}
select foo||'|'||bar ||'|'|| xyz from temp where dfg='some';
exit;
END_QUERY
4 голосов
/ 13 ноября 2009

Совет по использованию DBI хорош, и, безусловно, правильный способ сделать что-то, если вы хотите программировать сценарии Perl для баз данных.

Однако, чтобы ответить на ваш точный вопрос, если вы специально хотите писать скрипт SQL * Plus, синтаксис для этого со скриптом Perl довольно похож на версию оболочки

my $connect_string = 'scott/tiger@test';
my $sqlplus_settings = '';
my $result = qx { sqlplus $connect_string <<EOF
$sqlplus_settings
select 1 from dual;
exit;
EOF
};
print $result;

Оператор qx, который я здесь использую, - это просто политическая форма обратного удара, все в блоке с разделителями-скобками запускается подоболочкой, а вывод возвращается в назначение. Переменные обычно не прописываются в Perl.

1 голос
/ 14 ноября 2009

Любой вопрос этого типа должен начинаться с "Я не могу использовать DBI, потому что ..." Потому что вы действительно хотите использовать DBI, если это вообще возможно. У вас могут быть веские причины не использовать его, но, возможно, мы расскажем вам, почему ваши причины не очень хороши и что с этим делать. Тем не менее, вот один из способов сделать то, что вы просили, используя fork и filehandles, и получать выходные данные по одной строке за раз (предупреждение: если вы печатаете слишком много для такого процесса, он может блокироваться из-за проблем с буфером):

use strict;
use warnings;

pipe(my($p_rdr, $c_wtr)) or die "Err: $!";
pipe(my($c_rdr, $p_wtr)) or die "Err: $!";
my $pid = fork;
die "Could not fork: $!" unless defined $pid;
unless ($pid) {
  close $p_rdr;
  close $p_wtr;
  open(STDOUT, ">&=", $c_wtr) or die "dup: $!";
  open(STDIN, "<&=", $c_rdr) or die "dup: $!";
  print "Exec sqlplus\n";
  exec qw(sqlplus user/passwd@dbname);
  die "Could not exec: $!";
}
close $c_wtr;
close $c_rdr;
print "Print sql\n";
print $p_wtr "select * from table_name where col1 = 'something';\n";
print "Close fh\n";
close $p_wtr;

print "Read results\n";
while (<$p_rdr>) {
  print "O: $_";
}
close $p_rdr;
1 голос
/ 13 ноября 2009

Пара вещей:

  • DBI - определенно лучший путь. Однако, обратите внимание на предыдущий ответ, который я дал на вопрос Oracle, который, возможно, «все еще» актуален: Как я могу использовать сервер базы данных из сценария Perl CGI?

  • SQL * Plus выдает ошибку, если ваш SQL был слишком длинным. Он имеет буфер фиксированной длины строки (я не могу вспомнить, что это было, но я думаю, что это было ниже 2000 символов в Oracle 8). Может быть, есть обходной путь (разделение строк «настройки конфигурации»), но я нашел переключение на DBI лучшим решением по этой и другим причинам.

Предостережение: Вся моя информация выше основана на Oracle 8.

/ I3az /

...