I am trying to backup a Sql Server database via Perl DBI. Calling "backup database" via do() runs but usually does not produce a backup. Calling do() creates a backup when ODBC tracing is enabled. Calling prepare() and execute() fails.
I am using ActiveState Perl on Windows 7 Professional and Sql Server 2008 R2. Here is a link to download source code and various logs http://www.fileswap.com/dl/4VnYbCdk6R/ToZip.zip.html (Click on slow download)
Here is the summary of logs
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
Here's my program:
#!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;
2条答案
按热度按时间hfyxw5xn1#
There is nothing wrong with the Perl code you show. However, the ODBC trace file shows that DBD::ODBC made these calls just before the error:
I cannot for the life of me see how this is an invalid cursor state (look the valid state transitions for ODBC up yourself) so I'd have to say this looks like a bug in the SQL Server ODBC driver you are using. You could try getting a newer one or use the SQL Server native client driver instead (you've probably got both already).
You can ignore the errors in your sql server log as they are correct, error 1235 is ERROR_REQUEST_ABORTED which it was.
7cwmlq892#
As of now, using DBI 1.643 and DBH::ODBC 1.61, attempting to create a Backup using do() will generate the backup file temporarily while the backup statement is running but the backup file simply vanishes immediately after the statement is done. Using prepare() and execute(), though, seems to work just fine