В настоящее время у меня есть некоторые проблемы с настройкой интрасети с помощью ссылки odbc между AS400 (iseries V6R1), а в Debian я использую 64-битные драйверы iseriesAccess7.1 odbc 64 бит, unixODBC2.3.1 и php5.4 с поддержкой unixODBC.
Моя ссылка кажется хорошей, потому что я могу подключиться к своей базе данных с помощью команды isql (которая является частью unixODBC) и выполнить некоторые SQL-запросы, но невозможно прочитать записи в базе данных с помощью php-скрипта. Когда я пытаюсь запустить небольшой скрипт в моей интрасети, я получаю следующую ошибку:
Неустранимая ошибка: допустимый размер памяти 134217728 байт исчерпан (пытался выделить 493921239296 байт) в /home/www/imypdo/imypdo.php в строке 122
это больше, чем 450 Гб! и ничего в / var / log / messages и в / etc / httpd / logs / error_log
Простой запрос sql (только с 1 строкой в выборе) вернет некоторые странные символы (см. Ниже), и как только я выберу 1 или 2 строки, возникает ошибка размера памяти.
[0] => Массив ([ADHMAR] => AAAAAAA a @ YÿŒ4-X 0! ŸŒ4làÿŒ4làÿŒ4!)
Я почти уверен, что это проблема с 64-битным драйвером, потому что у меня уже есть другой Debian, связанный с этим сервером, но с 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-разрядный драйвер), что диспетчер драйверов, приложение и драйвер согласны с sizeof (SQLLEN). Варианты 32 и 64 бит. Я считаю, что драйверы IBM позволяют установить это через файл конфигурации. unixODBC 2.3 по умолчанию будет строить с sizeof (SQLLEN) = 64 бит. Как ваше приложение построено, я не могу сказать.
Драйвер ODBC iSeriesAccess для Linux 7.1 был скомпилирован против более старой версии unixODBC, которая указала 32-разрядный SQLLEN. Когда ваше приложение или промежуточное ПО (php в этом случае) скомпилированы против более новой версии unixODBC (начиная с версии 2.2.14), по умолчанию будет использоваться 64-разрядный SQLLEN. Поскольку драйвер только перезаписывает верхние 32-битные данные, результаты любого вызова API, который принимает указатель SQLLEN в качестве параметра, в этом сценарии не определены.
У вас есть два варианта: перекомпилируйте php с помощью BUILD_LEGACY_64_BIT_MODE set (-DBUILD_LEGACY_64_BIT_MODE) или используйте новый драйвер IBM i ODBC, который использует 64-разрядные SQLLEN. Дополнительную информацию о новом драйвере ODBC, включенном в пакет приложений IBM i Access Client Solutions Linux, можно найти в этой статье: http://www.ibm.com/developerworks/ibmi/library/i-ibmi-access-client- решений-linux, на которые ссылался Ник в приведенном выше комментарии. Вы можете узнать, как загрузить драйвер здесь: http://iprodeveloper.com/blog/how-do-you-actually-get-access-client-solutions
Мне кажется, что вы читаете таблицу, у текстовых полей которой есть неправильный CCSID, скорее всего, у них 65535, что означает hex / binary.
Таким образом, система не пытается перевести текст EBCDIC в ASCII для вас.
Правильный ответ заключается в том, чтобы изменить CCSID на правильное значение для данных в файле. 37 = USCDCD. Пока вы на нем, вы можете проверить их / изменить CCSID по умолчанию для системы. WKKSYSVAL QCCSID
Однако драйвер ODBC Windows предлагает настройку ForceTranslation (CCISD 65535).
Чарльз
Я понимаю это.
В 64-битной версии odbc падает, когда одно из полей возврата равно NULL. Таким образом, работа вокруг заключается в замене всех нулевых полей при возврате запроса.
пример :
выберите ifnull (tluser, '') в качестве USER из базы данных.table