2014-03-12 57 views
1

我有一個奇怪的問題。在我的開發電腦上,我收到錯誤。但是在現場系統上,錯誤不會發生。如果我解決了開發中的問題,修復會導致生產中出現問題。Perl DBI何時關閉預處理語句

它與我關閉準備好的語句時有關。在製作過程中,我必須在每次獲取後調用完成。如果我在我的開發系統上執行此操作,那麼語句的下一次執行將返回undef,並且$ dbh-> errstr或$ DBI :: errstr中沒有任何內容。

任何想法從哪裏開始呢?

下面是一個簡單的測試:

#!/usr/bin/perl 

use strict; 
use warnings; 

use DBI; 
use DateTime; 
use DateTime::Format::Strptime; 
use Data::Dumper; 

# Debug flag. 
my $debug = 1; 

#helper 
sub getLoggingTime { 

    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); 
    my $nice_timestamp = sprintf ("%04d/%02d/%02d %02d:%02d:%02d", 
           $year+1900,$mon+1,$mday,$hour,$min,$sec); 
    return $nice_timestamp; 
} 

# Debug function. 
sub dbg { if (! $debug) { return }; my $str = getLoggingTime() . " " . shift ; print STDERR $str } 

# These are *the* date and time formats we use. 
my $dateFormat = new DateTime::Format::Strptime('pattern' => '%F', 'locale' => 'en_NZ',    'time_zone' => 'Pacific/Auckland'); 
my $timeFormat = new DateTime::Format::Strptime('pattern' => '%T', 'locale' => 'en_NZ', 'time_zone' => 'Pacific/Auckland'); 

# Connect to the database. 
my $dbconnect = *****removed**** || die 'No dbi_connection configured.'; 
my $dbusername = *****removed**** || die 'No dbi_username configured.'; 
my $dbpassword = *****removed**** || die 'No dbi_password configured.'; 

my $dbh = DBI->connect ($dbconnect, $dbusername, $dbpassword, { RaiseError => 1, PrintError => 1, AutoCommit => 1 }) || 
    die 'Cannot connect to database. ' . DBI::errstr; 
my $test_sth = $dbh->prepare(' 
    SELECT 
     ? as teststring, 
     GETDATE() as testdate 
    ') || die 'Cannot prepare franchise name statement: ' . ($dbh->errstr ||$DBI::errstr || "") . "\n"; 


##Attempt One 
$test_sth->execute("Test string") || die "Could not execute test statement: " . ($dbh->errstr ||$DBI::errstr || "") . "\n"; 

my $result = $test_sth->fetchrow_hashref() 
|| die "Cannot get result: " . ($dbh->errstr ||$DBI::errstr || "") . "\n"; 
$test_sth->finish(); 

my $testString = $result->{'teststring'}; 
my $testDate = $result->{'testdate'}; 

dbg("testString = $testString, testDate = $testDate\n"); 


##Attempt Two 
$test_sth->execute("Test string") || die "Could not execute test statement: " . ($dbh->errstr ||$DBI::errstr || "") . "\n"; 

$result = $test_sth->fetchrow_hashref() 
|| die "Cannot get result: " . ($dbh->errstr ||$DBI::errstr || "") . "\n"; 
$test_sth->finish(); 

$testString = $result->{'teststring'}; 
$testDate = $result->{'testdate'}; 

dbg("testString = $testString, testDate = $testDate\n"); 

$dbh->disconnect(); 
1; 

在開發我得到:

perl的dbiTest.pl 2014年3月13日11時15分51秒的TestString =測試字符串,testDate = 2014年3月13日11:15 AM 無法執行的測試語句:PROD上

我得到:

dbiTest.pl 2014年3月13日11時17分20秒的TestString =測試字符串,testDate = 2014年3月13日上午11點17 2014年3月13日11時17分20秒的TestString =測試字符串,testDate = Mar 13 2014 11:17 AM

如果我評論第一個$ test_sth-> finish(); 在開發我得到:

perl的dbiTest.pl 2014年3月13日十一點24分44秒的TestString =測試字符串,testDate = 2014年3月13日上午11:24 2014年3月13日11:24: 44 testString = Test string,testDate = Mar 13 2014 11:24 AM on Prod我得到: perl dbiTest.pl 2014/03/13 11:18:06 testString = Test string,testDate = 2014年3月13日11:18 DBD :: Sybase :: st執行失敗:OpenClient消息:LAYER =(0)ORIGIN =(0)SEVERITY =(78)NUMBER =(51) 消息字符串:嘗試啓動一個新的Adaptive Server操作,並等待結果 DBD :: Sybase :: st執行失敗:OpenClient me ssage:LAYER =(0)ORIGIN =(0)嚴重性=(78)NUMBER =(51) 消息字符串:嘗試發起與結果的新的Adaptive服務器操作未決

UPDATE: 設置$dbh->{syb_flush_finish} = 1;允許開發系統運行完成而不會中斷。 這確實解決了我的問題,但並未解釋發生了什麼。

+1

開發機器和prod機器上的perl版本有區別嗎?我已經看到這些行爲與不同版本的行爲。 – Raghuveer

+2

是的,有prod是perl v5.10.1和dev是v5.14.2 –

+1

是很有可能的版本差異導致這個錯誤 – blueygh2

回答

1

您的版本DBD::Sysbase已過時。按照changelog,修復在1.01(釋放所有的方式早在2003年9月!),以

自動finish()聲明添加處理,如果他們重新執行所有行已提取之前。

v1還有另一個修復程序。06(2005年8月),因爲finish有時無法清理關聯的數據庫句柄。從v1.00開始有很多很多的變化,所以升級到最新版本並將呼叫放到finish