Linux odbc Erro fatal: tamanho de memory permitido

Atualmente, tenho alguns problemas para configurar uma intranet com um link odbc entre um AS400 (iseries V6R1) e um Debian. Eu uso o driver odbc iseriesAccess7.1, 64bits, unixODBC2.3.1 e php5.4 com suporte unixODBC.

Meu link parece ser bom porque eu posso me conectar ao meu DataBase usando o comando isql (que é parte do unixODBC) e executar algumas consultas SQL, mas é impossível ler registros no database usando um script php. Quando tento iniciar um pequeno script na minha intranet, recebo o seguinte erro:

Erro fatal: Tamanho da memory permitida de 134217728 bytes esgotados (tentou alocar 493921239296 bytes) em /home/www/imypdo/imypdo.php on line 122

isso é mais de 450 Gb !! e nada em / var / log / messages e em / etc / httpd / logs / error_log

Uma consulta sql simples (com apenas 1 linha na seleção) retornará alguns caracteres estranhos (veja abaixo) e, assim que eu selecionar 1 ou mais 2 linhas, ocorre o erro de tamanho da memory.

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

Estou quase certo de que é um problema relacionado ao driver de 64 bits porque já tenho outro Debian ligado a este iseries, mas com o driver de 32 bits e funciona perfeitamente. O que é estranho é que o comando isql está funcionando e não há nada nos arquivos de log …

se realmente é um problema de driver de 64 bits, como posso provar isso para a IBM?

Qualquer ajuda será apreciada

obrigado

————————— Classe para conectar ——————– ——–

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; } 

}

——————————— Script de consulta ————— —————

 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 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; } 

Eu verificaria (dado o seu driver de 64 bits) que o driver, o aplicativo e o driver concordam com o tamanho de (SQLLEN). As escolhas são 32 e 64 bits. Eu acredito que os drivers da IBM permitem que você defina isso através do arquivo de configuração. UnixODBC 2.3 será compilado por padrão com sizeof (SQLLEN) = 64 bits. Como o seu aplicativo está construído, eu não posso dizer.

O driver ODBC iSeriesAccess para Linux 7.1 foi compilado contra uma versão mais antiga do unixODBC que especificou um SQLLEN de 32 bits. Quando seu aplicativo ou middleware (php nesse caso) é compilado em uma versão mais recente do unixODBC (desde 2.2.14), o padrão usará um SQLLEN de 64 bits. Uma vez que o driver apenas substitui os 32 bits principais dos dados, os resultados de qualquer chamada de API que leva um ponteiro SQLLEN como um parâmetro são indefinidos neste cenário.

Você tem duas opções: recompile o php com BUILD_LEGACY_64_BIT_MODE set (-DBUILD_LEGACY_64_BIT_MODE) ou use o novo driver IBM i ODBC que usa SQLLENs de 64 bits. Você pode encontrar mais sobre o novo driver ODBC incluído no IBM i Access Client Solutions Linux Application Package neste artigo que escrevi: http://www.ibm.com/developerworks/ibmi/library/i-ibmi-access-client- soluções-linux que Nick referenciou em um comentário acima. Você pode descobrir como baixar o driver aqui: http://iprodeveloper.com/blog/how-do-you-actually-get-access-client-solutions

Soa comigo como se você estivesse lendo uma tabela cujos campos de texto possuíam um CCSID incorreto, provavelmente eles têm 65535 atribuídos o que significa hexadecimal / binário.

Portanto, o sistema não está tentando traduzir o texto EBCDIC para ASCII para você.

A resposta correta é obter a alteração CCSID para o valor correto para os dados no arquivo. 37 = US EBCDIC. Enquanto você estiver nisso, você pode fazê-los verificar / alterar o CCSID padrão do sistema. WRKSYSVAL QCCSID

No entanto, o driver ODBC do Windows oferece uma configuração, ForceTranslation (do CCISD 65535).

Charles

Eu entendo isso.

Na versão de 64 bits, o odbc trava quando um dos campos de retorno é NULL. Portanto, o trabalho em volta é para replace todos os campos nulos quando retriving a consulta.

exemplo:

selecione ifnull (tluser, ”) como USUÁRIO de database.table