为什么这个 Perl 代码在不同的机器上运行时返回不同的数据类型?
我是维护合同的新手,我以前从未使用过 Perl,这就是我发现的。
我有:
sub record {
my ( $dbh, $sth, $sql, %rs, %arg, @alias, $key, %default );
%default = ( db => '*', tabla => '*', campos => '*', condicion => '', campos => '*', alias => '*', visible => 'si' );
%arg = @_;
if ( $arg{campos} ) { $default{alias} = $arg{campos}; }
foreach $key ( keys %default ) {
if ( !exists $arg{$key} ) { $arg{$key} = $default{$key}; }
if ( exists $arg{$key} && $arg{$key} eq '' ) { $arg{$key} = $default{$key}; }
if ( $arg{$key} eq '*' ) { &msj( "Error !!!", "$key is needed" ); return; }
}
@alias = split /,/, $arg{alias};
$dbh = DBI->connect( "dbi:Pg:dbname=$arg{db}; host=$ipserver; port=5432", "postgres", "xxxx" ) or die "Error: $DBI::errstr";
if ( !$DBI::errstr ) {
$sql = "SELECT $arg{campos} FROM $arg{tabla} $arg{condicion}";
if ( $arg{visible} eq 'si' ) { &msj( "Consulta a la base de datos $arg{db}", $sql ); }
$sth = $dbh->prepare($sql) or die "No se ha preparado: $DBI::errstr";
$sth->execute;
@rs{@alias} = ();
if ( $DBI::rows > 0 ) {
$sth->bind_columns( map { \$rs{$_} } @alias );
}
return ( \%rs, sub { $sth->fetch() } );
$sth->finish;
$dbh->disconnect;
} else {
&mensaje( "Error !!!!", "No access to $arg{db}" );
exit;
}
}
要使用这个,我有类似的东西
( $rs, $fetch ) = record( db => "infodfsisadmon", tabla => "login", condicion => "where usuario='$FORM{usuario}' and clave='$FORM{clave}'", campos => "acceso,referencia,id_modulo,uaa,nivel_acceso,privilegios,activo,correo", visible => "si" );
# Show me the record
print "rs ->" . Dumper $rs;
当我在 Centos 5.6 的服务器上运行它时,我得到:
rs ->$VAR1 = {
'nivel_acceso' => '{"",NL,NL,NL,NL,"","","","","","","","","","","","","","","","","","","","","","","","",""}',
'correo' => '[email protected]',
'privilegios' => '{ADM,ADMINISTRADOR,ADM,ADM,1:AMEI:2:AMEI:3:AMEI:4:AMEI:5:AMEI,"","","","","","","","","","","","","","","","","","","","","",""," ","",""}',
'acceso' => '{t,t,t,t,t,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f}',
'referencia' => '{/cgi-bin/infodf/nomina/index.cgi,/cgi-bin/infodf/contable/index0.cgi,/cgi-bin/infodf/presupuesto/index0.cgi,/cgi-bin/infodf/nomina_fonacot/index.cgi,/cgi-bin/infodf/recmat/index.cgi,"","","","","","","","","","","","","","","","","","","","","","","","",""}',
'id_modulo' => '{1,2,3,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}',
'uaa' => '{"",002,002,002,002,"","","","","","","","","","","","","","","","","","","","","","","","",""}',
'activo' => '{t,t,t,t,t,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f}'
};
当我在 Centos 5.7 上运行它时,我得到的是:
rs ->$VAR1 = {
'nivel_acceso' => [ 'NL', 'NL', 'NL', 'NL', 'NL', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ],
'correo' => '[email protected]',
'privilegios' => [ 'ADM', 'ADMINISTRADOR', 'ADM', 'ADM', '1:AMEI:2:AMEI:3:AMEI:4:AMEI:5:AMEI', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' ', '', '' ],
'acceso' => [ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
'referencia' => [ '/cgi-bin/infodf/nomina/index.cgi', '/cgi-bin/infodf/contable/index0.cgi', '/cgi-bin/infodf/presupuesto/index0.cgi', '/cgi-bin/infodf/nomina_fonacot/index.cgi', '/cgi-bin/infodf/recmat/index.cgi', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ],
'id_modulo' => [ 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
'uaa' => [ 'CONS', '002', '002', '002', '002', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ],
'activo' => [ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
};
Perl on Centos 5.6 is perl5 (revision 5 version 8 subversion 8) on Centos 5.7 是 perl5(修订版 5 版本 8 颠覆 8),但 5.7 中的是 64 位,而 5.6 中的是32.
两台服务器都运行 postgresql-8.1,安装的 rpm 为:
5.6
postgresql-8.1.22-1.el5_5.1
postgresql-contrib-8.1.22-1.el5_5.1
postgresql-docs-8.1.22-1.el5_5.1
postgresql-jdbc-8.1.407-1jpp.4
postgresql-libs-8.1.22-1.el5_5.1
postgresql-odbc-08.01.0200-3.1
postgresql-pl-8.1.22-1.el5_5.1
postgresql-python-8.1.22-1.el5_5.1
postgresql-server-8.1.22-1.el5_5.1
postgresql-test-8.1.22-1.el5_5.1
5.7
postgresql-8.1.23-1.el5_7.3
postgresql-devel-8.1.23-1.el5_7.3
postgresql-libs-8.1.23-1.el5_7.3
postgresql-server-8.1.23-1.el5_7.3
自 DBI 和 DBD:Pg:
5.6
DBI 1.52
DBD::页 1.49
5.7
DBI 1.52
DBD::Pg 2.18.1
我不知道为什么会有区别。欢迎您提供提示、技巧和解释。
I am a the beginning of a maintenance contract, I've never done Perl before and this is what I found.
I have:
sub record {
my ( $dbh, $sth, $sql, %rs, %arg, @alias, $key, %default );
%default = ( db => '*', tabla => '*', campos => '*', condicion => '', campos => '*', alias => '*', visible => 'si' );
%arg = @_;
if ( $arg{campos} ) { $default{alias} = $arg{campos}; }
foreach $key ( keys %default ) {
if ( !exists $arg{$key} ) { $arg{$key} = $default{$key}; }
if ( exists $arg{$key} && $arg{$key} eq '' ) { $arg{$key} = $default{$key}; }
if ( $arg{$key} eq '*' ) { &msj( "Error !!!", "$key is needed" ); return; }
}
@alias = split /,/, $arg{alias};
$dbh = DBI->connect( "dbi:Pg:dbname=$arg{db}; host=$ipserver; port=5432", "postgres", "xxxx" ) or die "Error: $DBI::errstr";
if ( !$DBI::errstr ) {
$sql = "SELECT $arg{campos} FROM $arg{tabla} $arg{condicion}";
if ( $arg{visible} eq 'si' ) { &msj( "Consulta a la base de datos $arg{db}", $sql ); }
$sth = $dbh->prepare($sql) or die "No se ha preparado: $DBI::errstr";
$sth->execute;
@rs{@alias} = ();
if ( $DBI::rows > 0 ) {
$sth->bind_columns( map { \$rs{$_} } @alias );
}
return ( \%rs, sub { $sth->fetch() } );
$sth->finish;
$dbh->disconnect;
} else {
&mensaje( "Error !!!!", "No access to $arg{db}" );
exit;
}
}
To use this I have something like
( $rs, $fetch ) = record( db => "infodfsisadmon", tabla => "login", condicion => "where usuario='$FORM{usuario}' and clave='$FORM{clave}'", campos => "acceso,referencia,id_modulo,uaa,nivel_acceso,privilegios,activo,correo", visible => "si" );
# Show me the record
print "rs ->" . Dumper $rs;
When I run this on a server with Centos 5.6 I get:
rs ->$VAR1 = {
'nivel_acceso' => '{"",NL,NL,NL,NL,"","","","","","","","","","","","","","","","","","","","","","","","",""}',
'correo' => '[email protected]',
'privilegios' => '{ADM,ADMINISTRADOR,ADM,ADM,1:AMEI:2:AMEI:3:AMEI:4:AMEI:5:AMEI,"","","","","","","","","","","","","","","","","","","","","",""," ","",""}',
'acceso' => '{t,t,t,t,t,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f}',
'referencia' => '{/cgi-bin/infodf/nomina/index.cgi,/cgi-bin/infodf/contable/index0.cgi,/cgi-bin/infodf/presupuesto/index0.cgi,/cgi-bin/infodf/nomina_fonacot/index.cgi,/cgi-bin/infodf/recmat/index.cgi,"","","","","","","","","","","","","","","","","","","","","","","","",""}',
'id_modulo' => '{1,2,3,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}',
'uaa' => '{"",002,002,002,002,"","","","","","","","","","","","","","","","","","","","","","","","",""}',
'activo' => '{t,t,t,t,t,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f,f}'
};
When I run it on Centos 5.7 what I get is:
rs ->$VAR1 = {
'nivel_acceso' => [ 'NL', 'NL', 'NL', 'NL', 'NL', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ],
'correo' => '[email protected]',
'privilegios' => [ 'ADM', 'ADMINISTRADOR', 'ADM', 'ADM', '1:AMEI:2:AMEI:3:AMEI:4:AMEI:5:AMEI', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' ', '', '' ],
'acceso' => [ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
'referencia' => [ '/cgi-bin/infodf/nomina/index.cgi', '/cgi-bin/infodf/contable/index0.cgi', '/cgi-bin/infodf/presupuesto/index0.cgi', '/cgi-bin/infodf/nomina_fonacot/index.cgi', '/cgi-bin/infodf/recmat/index.cgi', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ],
'id_modulo' => [ 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
'uaa' => [ 'CONS', '002', '002', '002', '002', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ],
'activo' => [ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
};
Perl on Centos 5.6 is perl5 (revision 5 version 8 subversion 8) on Centos 5.7 is perl5 (revision 5 version 8 subversion 8) but the in 5.7 is 64 bits while the one in 5.6 is 32.
Both servers are running postgresql-8.1, the rpms installed are:
5.6
postgresql-8.1.22-1.el5_5.1
postgresql-contrib-8.1.22-1.el5_5.1
postgresql-docs-8.1.22-1.el5_5.1
postgresql-jdbc-8.1.407-1jpp.4
postgresql-libs-8.1.22-1.el5_5.1
postgresql-odbc-08.01.0200-3.1
postgresql-pl-8.1.22-1.el5_5.1
postgresql-python-8.1.22-1.el5_5.1
postgresql-server-8.1.22-1.el5_5.1
postgresql-test-8.1.22-1.el5_5.1
5.7
postgresql-8.1.23-1.el5_7.3
postgresql-devel-8.1.23-1.el5_7.3
postgresql-libs-8.1.23-1.el5_7.3
postgresql-server-8.1.23-1.el5_7.3
As of DBI and DBD:Pg:
5.6
DBI 1.52
DBD::Pg 1.49
5.7
DBI 1.52
DBD::Pg 2.18.1
I have no idea why the difference. Your hints, tips and explanations are all welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我有信心两台机器之间的软件堆栈存在版本差异,其中包括:
至少这些层中的一层或可能有几层是不同的。您声明服务器在两者上都是 PostgreSQL 8.1;这表明问题出在客户端库或 DBD::Pg 中。相对而言,Perl 版本或 DBI 版本不太可能出现问题,但这可能在一定程度上取决于两个版本(Perl 和 DBI)的差异程度。差异不太可能是由于操作系统版本造成的。
旧代码(在 Centos 5.6 上)返回数组中数据的字符串形式。较新的代码可以更自然地处理数组。这仍然无法解释新字段中的
$rs->uaa->[0]
与旧字段中的第一个(空)字段之间的区别,但确实解释了其余大部分字段。Perl DBI 对于相关版本的绝对数量要求异常高。但是,我认为您的问题源于旧的
DBD::Pg
模块。根据http://search.cpan.org/,
我建议在两台机器上升级到相同的更新版本,或者使旧版本与旧机器上的新版本保持一致。 DBI 版本不太可能成为问题的根源,但升级到最新版本仍然会很好。
I'm modestly confident that you have a version difference between the two machines in the software stack, which consists of:
At least one and possibly several of those layers are different. You state that the server is PostgreSQL 8.1 on both; that suggests the issue is in the client-side library or DBD::Pg. It is relatively unlikely to be an issue with either the version of Perl or the version of DBI, but that might depend a bit on how different the two versions (of Perl and DBI) are. It is very unlikely that the difference is due to the o/s version.
The older code (on Centos 5.6) is returning a string form of the data in the arrays. The newer code is handling the arrays more naturally. That still doesn't explain the difference between
$rs->uaa->[0]
in the new and the first (empty) field in the old, but does account for most of the rest.Perl DBI is unusually demanding in the sheer number of versions that could be relevant. However, I think your problems stem from the old
DBD::Pg
module.According to http://search.cpan.org/,
I recommend upgrading to the same more recent version on both machines, or bringing the older version into line with the new version on the older machine. The DBI version is less likely to be the source of the trouble, but it would still be good to upgrade to the most current version.