什么原因导致DBD :: ODBC :: st fetchrow_array失败:st_fetch / SQLFetch以及如何避免它?

时间:2016-01-06 20:58:30

标签: arrays json perl hash

EDIT1:

我实际上没有得到如下所述的空阵列。相反,由于以下异常,我得到一个空的响应主体:

DBD::ODBC::st fetchrow_array failed: st_fetch/SQLFetch (long truncated DBI attribute LongTruncOk not set and/or LongReadLen too small) (SQL-HY000) [state was HY000 now 01004]

我可以看到哪些帖子有关。我会看看那些,看看我是否能解决这个问题。如果不成功,将进行编辑。

首先让我先说,我根本不了解Perl。这可能是一个粗心的错误 - 我希望是这样。我正在从SQL返回的数组或前端的JavaScript以及散列中的一个键中构建一个哈希," short-desc"需要具有以下代码中的值来自SQL数据库。

BFHHOTH 15x24S/S +2 UP-HNDWHL-UNSPOKED-GALV 15"x24" flush escape hatch w/hinge, internal handwheel, T-handle on top steel cover and ring

然而,使用代码(从交换机中删除了不必要的情况):

#!perl
use Switch;
use DBI;
use JSON;
use CGI qw /param/;
use CGI::Carp qw(fatalsToBrowser);
use IO::Compress::Gzip qw(gzip $GzipError);
use URI::Encode;
use URI::Escape;

my $gzip_ok;

my $accept_encoding = $ENV{HTTP_ACCEPT_ENCODING};
if ( $accept_encoding && $accept_encoding =~ /\bgzip\b/ ) {
 # $gzip_ok = 1;
}
print "Content-Type: application/json\n";
if ($gzip_ok) {
    print "Content-Encoding: gzip\n";
}
print "\n";

my $action = param('ACTION');

my %jsonData;
my @jsonArray;

my $azDSN = DBI->connect('dbi:ODBC:Driver={SQL Server Native Client 10.0};Server=myServer;Database=myDB;Uid=me;Pwd={myPass};Encrypt=yes;Connection Timeout=30;');

switch ($action) {
 case "GETINFO" {
    my $paramID = param('ID');
    getInfo($paramID);
     my $json_text = JSON->new->pretty->utf8->encode( \@jsonArray );
    if ($gzip_ok) {
        my $zipText;
        gzip \$json_text, \$zipText,
            or die "gzip failed: $GzipError\n";
        print $zipText;
    }
    else {
        print $json_text;
    }
  }
}

sub getInfo {
 my $myID = $_[0];
 my $statement = <<"SQL";
   SELECT
     trefQuoteItemsID,
     quote_position,
     description,
     comments
   FROM
     myDB.dbo.myTable where tID = $myID;
 SQL
 my $sti = $azDSN->prepare($statement) or die $statement;
 $sti->execute() or die $DBI::errstr;
 while ( my @row = $sti->fetchrow_array ) {
     my %tempData;

     %tempData = (
         "tref"                      => $row[0],
         "position"                  => $row[1],
         "short_desc"                => $row[2],
         "comments"                  => $row[3]
     );
     $jsonArray[$count] = {%tempData};
     $count++;
 }
}

在前端向我返回一个空数组。

奇怪的是,如果字符串是:

BFHHOTH 15x24S/S +2 UP-HNDWHL-UNSPOKED-

数组包含正确的对象。 但如果字符串是:

,则再次清空
BFHHOTH 15x24S/S +2 UP-HNDWHL-UNSPOKED-G

还试过字符串:

qwertyuiopasdfghjklzxcvbnm1234567890qwe  #length is 39

允许哈希构建并且:

qwertyuiopasdfghjklzxcvbnm1234567890qwer #length is 40

将返回一个空数组,因此哈希不会构建。

是否有任何Perl大师有任何建议?

1 个答案:

答案 0 :(得分:0)

据我所知,它与&#34;长对象&#34;有关。列。

DBD :: ODBC说:

  

您可以像这样检索块中的高亮:

$sth->bind_col($column, undef, {TreatAsLOB=>1});
while(my $retrieved = $sth->odbc_lob_read($column, \my $data, $length)) {
    print "retrieved=$retrieved lob_data=$data\n";
}
     

注意:要检索这样的lob,你必须首先绑定lob列,指定BindAsLOB或DBD :: ODBC将1)正常绑定列,它将受到LongReadLen和b)odbc_lob_read失败。

     

注意:某些数据库引擎和ODBC驱动程序不允许您不按顺序检索列(例如,MS SQL Server,除非您使用游标)。在这些情况下,您必须确保检索到的lob是选择列表中的最后一个(或唯一)列。

     

注意:您只能检索部分文件,但在使用该语句执行任何其他操作之前,您可能必须在语句句柄上调用finish。当只检索一个大吊球的一部分时,你可以看到一个小的延迟当你调用完成时,因为ODBC驱动程序使用的一些协议同步向下发送套接字并且没有办法阻止它(这意味着ODBC驱动程序需要读取所有尽管你自己从来没有检索过它,但是来自插座的吊灯。)

     

注意:如果您的选择包含多个lobs,则无法读取第一个lob的一部分,第二个lob将返回第一个lob。你必须按顺序阅读所有的lobs,或者阅读部分文件,然后不再打电话给odbc_lob_read。

如果你能以任何其他方式取回吊球,那么就没有提及,所以我不知道你是否必须这样做,但至少你知道一种方式。但我相信您可以通过增加连接的LongReadLen属性来解决问题。

您应该能够按如下方式设置属性:

my $dbh = DBI->connect($dsn, $user, $passwd, {
   ...,
   LongReadLen => ...,
});

您还应该能够按如下方式设置属性:

$dbh->{LongReadLen} = ...;

希望有人可以给你一个更好的答案。