Linux odbc致命错误:允许的内存大小

我目前有一些问题,build立一个AS400(iseries V6R1)和Debian我使用iseriesAccess7.1 odbc驱动程序64位,unixODBC2.3.1和PHP5.4与unixODBC支持odbc链接。

我的链接似乎是好的,因为我可以使用isql命令(它是unixODBC的一部分)连接到我的数据库并执行一些SQL查询,但是不可能使用php脚本读取数据库中的logging。 当我尝试在Intranet上启动一个小脚本时,出现以下错误:

致命错误:允许内存大小134217728字节用尽(尝试分配493921239296字节)在/ home / www / imypdo / imypdo.php在线122

这是超过450千兆! 而在/ var / log / messages和/ etc / httpd / logs / error_log中什么都没有

一个简单的sql查询(在select中只有一行)将返回一些奇怪的字符(见下文),一旦我select了1或2行以上的内存大小错误发生。

[0] => Array([ADHMAR] => AAAAAAA a @YÿŒ4-X 0!l4lÿÿÿ4làÿŒ4!)

我几乎可以肯定,这是一个64位驱动程序相关的问题,因为我已经有另一个Debian与这个iseries链接,但与32位驱动程序,它的作品完美。 奇怪的是,isql命令正在工作,而且在日志文件中什么也没有…

如果真的是64位的驱动程序问题,我该如何向IBMcertificate?

任何帮助将不胜感激

谢谢

—————————类连接——————– ——–

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位的驱动程序),驱动程序管理器,应用程序和驱动程序在sizeof(SQLLEN)上达成一致。 选择是32位和64位。 我相信IBM的驱动程序让你通过配置文件来设置。 unixODBC 2.3将默认使用sizeof(SQLLEN)= 64位构建。 你的应用程序如何建立我不能说。

iSeriesAccess for Linux 7.1 ODBC驱动程序是针对旧版本的指定32位SQLLEN的unixODBC编译的。 当您的应用程序或中间件(本例中为php)针对较新版本的unixODBC(自2.2.14)进行编译时,默认情况下将使用64位SQLLEN。 由于驱动程序只覆盖数据的前32位,因此在此场景中,将SQLLEN指针作为参数的任何API调用的结果都是未定义的。

您有两种选择:使用BUILD_LEGACY_64_BIT_MODE集合(-DBUILD_LEGACY_64_BIT_MODE)重新编译php,或使用新的使用64位SQLLEN的IBM i ODBC驱动程序。 在本文中,您可以找到更多关于IBM i Access Client解决方案Linux应用程序包中包含的新ODBC驱动程序的信息: http : //www.ibm.com/developerworks/ibmi/library/i-ibmi-access-client-解决方案-linux在上面评论中引用了Nick。 你可以找到如何在这里下载驱动程序: http : //iprodeveloper.com/blog/how-do-you-actually-get-access-client-solutions

听起来像你正在读一个表的文本字段有一个不正确的CCSID,很可能他们有65535分配,这意味着十六进制/二进制。

所以系统不会试图将EBCDIC文本转换为ASCII码。

正确的答案是将CCSID更改为文件中数据的正确值。 37 =美国EBCDIC。 当你在这里,你可以让他们检查/更改系统的默认CCSID。 WRKSYSVAL QCCSID

但是,Windows ODBC驱动程序确实提供了一个设置,强制转换(CCISD 65535)。

查尔斯

我知道了。

在64位版本中,当其中一个返回字段为NULL时,odbc崩溃。 所以解决这个问题的方法是在重新查询时替换所有的空字段。

例如:

从database.table中选择ifnull(tluser,'')作为USER