2014-01-10 2 views
1

Я пытаюсь создать резервную копию базы данных Sql Server через Perl DBI. Вызов «резервной базы данных» с помощью do() выполняется, но обычно не создает резервной копии. Calling do() создает резервную копию при включенной трассировке ODBC. Вызов метода prepare() и execute() завершается с ошибкой.Как использовать Perl DBI для резервного копирования SQL Server

Я использую ActiveState Perl для Windows 7 Professional и Sql Server 2008 R2. Вот ссылка для загрузки исходного кода и различных журналов http://www.fileswap.com/dl/4VnYbCdk6R/ToZip.zip.html (Нажмите на медленной загрузке)

Вот резюме бревен

BothTraces made 3 backups but program aborted 
-rwx------+ 1 SYSTEM SYSTEM 160256 Jan 16 09:39 perlEasy.bak 
-rwx------+ 1 SYSTEM SYSTEM 160256 Jan 16 09:39 perlHard.bak 
-rwx------+ 1 SYSTEM SYSTEM 160256 Jan 16 09:38 queryOS.bak 

NoTracing made 1 backup, program aborted 
-rwx------+ 1 SYSTEM SYSTEM 160256 Jan 16 10:15 queryOS.bak 

DbiTrace made 1 backup, program aborted 
-rwx------+ 1 SYSTEM SYSTEM 160256 Jan 16 10:19 queryOS.bak 

OdbcTrace made 3 backup but program aborted 
-rwx------+ 1 SYSTEM SYSTEM 159744 Jan 16 10:21 perlEasy.bak 
-rwx------+ 1 SYSTEM SYSTEM 160256 Jan 16 10:21 perlHard.bak 
-rwx------+ 1 SYSTEM SYSTEM 160256 Jan 16 10:21 queryOS.bak 

Вот моя программа:

#!perl -w 
#try to use DBI for SQL Server backup 

#connect to database server 
    use v5.14;  #enable modern Perl 
    use DBI;   #database interface 
    my $dbHandle = DBI->connect("dbi:ODBC:Driver={SQL Server};Server=DavidZ") or die; #dbi prints a detailed error message 
    $dbHandle->{RaiseError} = 1; #enable failure on DBI problems; obviates the need for "or die" with every DBI call 
    $dbHandle->{PrintError} = 0; #don't duplicate error messages 

#enable debugging 
    $dbHandle->trace(1); 
    $dbHandle->{odbc_trace} = 1;         #not helpful 
    $dbHandle->{odbc_trace_file} = 'C:\David\dump\tracer.file'; #not helpful 

#run a SQL command to verify connection, write a note to ERRORLOG 
    $dbHandle->do ('use master'); 
    $dbHandle->do ("raiserror ('New run of backup.pl', 0, 0) with log"); 
    say 'Verified database connection'; 

#backup commands 
    my $perlEasy = "backup database dz to disk='C:\\David\\dump\\perlEasy.bak'"; 
    my $perlHard = "backup database dz to disk='C:\\David\\dump\\perlHard.bak'"; 
    my $queryOS = "backup database dz to disk='C:\\David\\dump\\queryOS.bak'"; 

#make a backup via sqlcmd. this works 
    my $sysCmd = "sqlcmd -Q \"$queryOS\" "; 
    system ($sysCmd) == 0 
     or die "The following system command failed: $sysCmd \n"; 
    say 'Created backup via sqlcmd'; 

#try to make a backup via DBI 
    $dbHandle->do ($perlEasy); #runs silently but does not produce a backup file 
    say 'Created backup the easy way'; 

#more complicated DBI method 
    my $stHandle = $dbHandle->prepare($perlHard); 
    $stHandle->execute();  #statement starts a backup then fails, no furter code is executed 

    do 
    { 
    #print dbi results 
    say "DBI reports $DBI::errstr"; 

    while (my @row = $stHandle->fetchrow_array()) #recommended by someone, but makes no sense for a backup 
     { say "Returned values: @row" }    #recommended by someone, but makes no sense for a backup 
    } while ($stHandle->{odbc_more_results}); 

    say 'Created backup the hard way'; 

#program completion 
    say 'Program completed successfully'; 
    exit 0; 
+0

Значит, вы не можете найти 'C: \ David \ dump \ perlEasy.bak' на локальном SQL Server или любых других файлах резервной копии? Должен ли журнал SQL Server (доступный из студии управления) сказать, что резервная копия была успешной? –

+0

Я поддерживаю DBD :: ODBC. Некоторые из этих советов исходят от https://metacpan.org/pod/release/MJEVANS/DBD-ODBC-1.45/FAQ#Why-does-my-backup-restore-some_other_procedure-in-MS-SQL-Server-not- полный. Не могли бы вы запустить сценарий еще раз после того, как сначала установите env var DBI_TRACE с помощью DBI_TRACE = DBD = x.log и вставьте конец журнала где-нибудь. Также было бы полезно включить отслеживание в администраторе ODBC и для нас, чтобы понять, что это значит. – bohica

ответ

0

Там нет ничего плохого в коде Perl, который вы показываете. Однако файл ODBC трассировка показывает, что DBD :: ODBC сделал эти вызовы как раз перед ошибкой:

SQLPrepare backup database dz to disk='C:\David\dump\perlHard.bak' 
SQLExecute returns SQL_SUCCESS_WITH_INFO and 
    Processed 208 pages for database 'dz', file 'dz_test' on file 1. (4035) 
then a few calls for various handles to SQLErrorW 
SQLRowCount returns ok and -1 for row count 
SQLNumResultCols returns SQL_ERROR and ]Invalid cursor state 

Я не могу за жизнь мне понять, как это состояние недопустимого курсора (смотрите допустимые переходы между состояниями для ODBC), поэтому я должен сказать, что это похоже на ошибку в используемом вами драйвере ODBC SQL Server. Вы можете попробовать получить более новую версию или использовать собственный клиентский драйвер SQL Server (у вас, вероятно, уже есть оба).

Вы можете игнорировать ошибки в вашем сервере SQL Server, поскольку они верны, ошибка 1235 - это ERROR_REQUEST_ABORTED, которой она была.

Смежные вопросы