我当前有一些问题可以在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