Perl DBI何时关闭预准备语句

时间:2014-03-12 22:06:26

标签: perl sybase dbi

我有一个奇怪的问题。在我的开发计算机上,我遇到了错误。但是在实时系统上,错误不会发生。如果我修复dev上的问题,修复会导致生产中出现问题。

这与我关闭准备好的陈述有关。在制作时我必须在每次获取后调用完成。如果我在我的开发系统上执行此操作,那么语句的下一个执行将返回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/03/13 11:15:51 testString =测试字符串,testDate = 2014年3月13日上午11:15   无法执行测试语句:

on Prod我得到:

  

dbiTest.pl   2014/03/13 11:17:20 testString =测试字符串,testDate = 2014年3月13日上午11:17   2014/03/13 11:17:20 testString =测试字符串,testDate = 2014年3月13日上午11:17

如果我评论第一个$ test_sth-> finish(); 在开发中我得到:

  

perl dbiTest.pl    2014/03/13 11:24:44 testString =测试字符串,testDate = 2014年3月13日上午11:24   2014/03/13 11:24:44 testString =测试字符串,testDate = 2014年3月13日上午11:24   在Prod我得到:   perl dbiTest.pl   2014/03/13 11:18:06 testString =测试字符串,testDate = 2014年3月13日上午11:18   DBD :: Sybase :: st执行失败:OpenClient消息:LAYER =(0)ORIGIN =(0)SEVERITY =(78)NUMBER =(51)   消息字符串:尝试启动具有挂起结果的新Adaptive Server操作   DBD :: Sybase :: st执行失败:OpenClient消息:LAYER =(0)ORIGIN =(0)SEVERITY =(78)NUMBER =(51)   消息字符串:尝试启动具有待处理结果的新Adaptive Server操作

更新 设置$dbh->{syb_flush_finish} = 1;允许开发系统运行完成而不是中断。 这确实解决了我的问题,但没有解释发生了什么。

1 个答案:

答案 0 :(得分:1)

您的DBD::Sysbase版本已过时。根据{{​​3}},在v1.01中添加了一个修复程序(2003年9月一直发布!)到

  

自动finish()语句处理是否在获取所有行之前重新执行它们。

v1.06(2005年8月)还有另一个修复,因为finish有时无法清理关联的数据库句柄。自v1.00以来已经有很多很多变化,所以升级到最新版本并将调用放到finish