Linux ODBC致命错误:允许记忆尺寸



我当前有一些问题可以在AS400(Iseries v6r1)和Debian I使用IseriesAccess7.1 ODBC驱动程序64BITS,UNIXODBC2.3.3和PHP5之间设置Intranet。.4在UnixODBC支持中。

我的链接似乎很好,因为我可以使用ISQL命令(是UnixODBC的一部分)连接到数据库并执行一些SQL查询,但是不可能使用PHP脚本在数据库中读取记录。当我尝试在Intranet上启动一个小脚本时,我会收到以下错误:

致命错误:允许的内存大小为134217728字节耗尽(试图分配493921239296字节)在/home/www/imypdo/imypdo/imypdo.php上

那超过450 GB!在/var/log/sakess和/etc/httpd/logs/error_log

中,没有任何内容

一个简单的SQL查询(选择中只有1行)将返回一些奇怪的字符(请参见下文),一旦我选择1或2行,内存大小错误就会发生。

[0] => array([[adhmar] => aaaaaaa a@y²4– x 0!4là®

我几乎确定这是一个与64位驱动程序相关的问题,因为我已经有另一个Debian与此iSeries链接,但是与32位驱动程序相关,并且可以很好地工作。很奇怪的是,ISQL命令正在工作,而在日志文件中没有什么...

如果确实是一个64位驱动程序问题,我该如何向IBM证明它?

任何帮助将不胜感激

谢谢

态------------

private $_bdd = "DSN=db2;",
        $_user = "USERNAME",
        $_pwd = "Password";
private $_con,
        $_isConnected;

public function open_connection(){
    $this->_con = odbc_connect ($this->_bdd, $this->_user, $this->_pwd ) or die("Error Connection") ;
    $this->_isConnected = true;
}
public function close_connection(){
     odbc_close($this->_con);
     $this->_isConnected = false;
}
public function execute($sql){
    if(!($this->_isConnected))
        $this->open_connection();
    #execute sql
    $res = odbc_exec($this->_con, $sql);
    return $res;
}
public function fetchRow($res){
    $row = odbc_fetch_array($res);
    return $row;
}

}

-----------------------------------------------------------------------------------------------------》----------------------

public function getPhoneLogsByDate($startDate, $endDate) {
    $startDate  = date('Ymd', strtotime($startDate));
    $endDate    = date('Ymd', strtotime($endDate));
    $rr = new As400_Model_as400query();
    $rr->open_connection();
    $sql = "select trim(tluser) as USER, trim(tlacct) as CLIENT, trim(concat(concat(concat(concat(concat(concat(substr(trim(tldate),1,4),'-'),substr(trim(tldate),5,2)),'-'),substr(trim(tldate),7,2)),' '), concat(concat(concat(concat(substr( substr(trim(tltime+1000000),2,6),1,2),':'),substr(substr(trim(tltime+1000000),2,6),3,2)),':'), substr(substr(trim(tltime+1000000),2,6),5,2)))) as DATETIME 
            ,trim(concat(concat(concat(concat(concat(concat(concat(concat(concat(concat(trreas,'|'),trsr01),'|'),trsr02),'|'),trsr03),'|'),trsr04),'|'),trsr05)) as REASONS
            ,trim(concat(concat(concat(tnnot1,tnnot2),tnnot3),tnnot4)) as NOTES
            from cabledta.tlogmstr left join cabledta.tlogreas on trnum#=tlnum#  left join cabledta.tlognote on tnnum#=tlnum#
            where tldate>='".$startDate."' and tldate <='".$endDate."'";

    $res = $rr->execute($sql);
    $response = array();

    while ($row = $rr->fetchRow($res)){
        $response[] = array(
                                'userName'      => $row['USER'],
                                'clientNumber'  => $row['CLIENT'],
                                'logDateTime'   => $row['DATETIME'],
                                'logReasons'    => $row['REASONS'],
                                'logNotes'      => utf8_encode($row['NOTES'])
                            );
    }
    $rr->close_connection();
return $response;
}

我弄清楚了。

在64位版本中,当返回字段之一为null时,ODBC崩溃。因此,周围的工作是在检索查询时替换所有空字段。

示例:

从数据库中选择ifnull(tluser,'')作为用户。Table

Linux 7.1 ODBC驱动程序的IseriesAccess是针对较旧版本的UnixoDBC编译的,该版本指定了32位SQLLEN。当您的应用程序或中间件(在这种情况下为PHP)是针对UnixoDBC(自2.2.14)的较新版本编译时,默认情况下将使用64位SQLLEN。由于驱动程序仅覆盖数据的前32位,因此在这种情况下,以SQLLEN指针为参数的任何API调用的结果。

您有两个选项:带有build_legacy_64_bit_mode set(-dbuild_legacy_64_bit_mode)的重新编译PHP或使用新的IBM I ODBC驱动程序,使用64位SQLLENS。您可以在本文中找到有关IBM I访问client linux应用程序包中包含的新的ODBC驱动程序的更多信息:尼克在上述评论中引用的解决方案莱诺。您可以在此处找到如何下载驱动程序:http://iprodeveloder.com/blog/how-do-you-actallal-actally-get-access-client-solutions

我将检查(鉴于其64位驱动程序),驱动程序管理器,应用程序和驱动程序在sizeof(sqllen)上达成协议。选择是32位和64位。我相信IBM驱动程序可让您通过配置文件设置此功能。UnixODBC 2.3默认情况下将使用sizeof(sqllen)= 64位构建。我不能说您的应用程序是如何构建的。

在我看来,就像您正在阅读一张文本字段不正确的ccsid,很可能是分配了65535,这意味着六边形/二进制。

因此,系统不会尝试将EBCDIC文本转换为ASCII。

正确的答案是将CCSID更改为文件中数据的正确值。37 =美国EBCDIC。当您使用时,可以让他们检查/更改系统的默认CCSID。wrksysval qccsid

但是,Windows ODBC驱动程序确实提供了设置,即CCISD 65535)。

charles

相关内容

  • 没有找到相关文章

最新更新