У меня есть сервер Debian (64 бита), и я хочу подключить его к базе данных AS400 через PHP. Я установил IBM i Access для Linux и unixodbc. Я следовал этому уроку: https://www.albertopicado.es/conexion-odbc-con-base-de-datos-db2-en-un-servidor-ibm-iseries/ хотя по-испански вы можете видеть процесс, которым я следовал.
Дело в том, что я могу сделать простое соединение, как:
$server= 'DRIVER={DRIVER_NAME};DATABASE=DATABASENAME;SYSTEM=IP;HOSTNAME=IP;PORT=NUMBER_OF_THE_PORT;PROTOCOL=TCPIP;';
$as400= odbc_connect($server, "username", "password");
$as400 ? echo "ok" : echo "ko";
Это возвращение «хорошо», поэтому я понимаю, что соединение установлено. Затем я делаю простой odbc_prepare, как показано ниже:
$query="SELECT * FROM DATABASE.TABLE WHERE ID=1;
$result=odbc_prepare($as400,$query);
Это приводит меня к неустранимой ошибке: допустимый объем памяти 1048576000 байт исчерпан (попытался выделить 140707423584261 байт).
Я увеличил значение memory_limit в файле php.ini до 1000M, и он по-прежнему выдает ту же ошибку. Я занимался серфингом в интернете и нашел людей, имеющих проблемы с 64-битными версиями, как в этом посте: Linux odbc Неустранимая ошибка: допустимый объем памяти но выполняемый запрос не имеет нулевого значения.
Информация
Команда odbcinst -j:
DRIVERS............: /usr/local/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
odbcinst.ini:
[iSeries Access ODBC Driver]
Description=iSeries Access for Linux ODBC Driver
Driver=/opt/ibm/iSeriesAccess/lib64/libcwbodbc.so
Setup=/opt/ibm/iSeriesAccess/lib64/libcwbodbcs.so
NOTE1=If using unixODBC 2.2.11 or later and you want the 32 and 64-bit ODBC drivers to share DSN's,
NOTE2=the following Driver64/Setup64 keywords will provide that support.
Driver64=/opt/ibm/iSeriesAccess/lib64/libcwbodbc.so
Setup64=/opt/ibm/iSeriesAccess/lib64/libcwbodbcs.so
Threading=2
DontDLClose=1
UsageCount=2
[iSeries Access ODBC Driver 64-bit]
Description=iSeries Access for Linux 64-bit ODBC Driver
Driver=/opt/ibm/iSeriesAccess/lib64/libcwbodbc.so
Setup=/opt/ibm/iSeriesAccess/lib64/libcwbodbcs.so
Threading=2
DontDLClose=1
UsageCount=1
odbc.ini пуст.
Видя, что, возможно, в драйвере iSeriesAccess x64 есть некоторые ошибки, я, наконец, удалил его. Затем я установил драйвер iSeriesAccess x32. Перед установкой нового драйвера я установил многоархивную версию Debian и загрузил ia32-libs (потому что некоторые драйверы для iSeriesAccess Driver x32 отсутствовали).
С новым драйвером я получаю еще одну ошибку:
Предупреждение: odbc_connect (): ошибка SQL: [unixODBC] [Driver Manager] Не удается открыть lib ‘/opt/ibm/iSeriesAccess/lib/libcwbodbc.so’: файл не найден, состояние SQL 01000 в SQLConnect.
Я дважды проверил, что lib ‘libcwbodbc.so’ существует. Я также запускаю команду ldd для lib, чтобы увидеть, что-то не хватает:
linux-gate.so.1 (0xf7763000)
libcwbcore.so => /opt/ibm/iSeriesAccess/lib/libcwbcore.so (0xf7557000)
libodbcinst.so.1 => /usr/lib/i386-linux-gnu/libodbcinst.so.1 (0xf7544000)
libdl.so.2 => /lib/i386-linux-gnu/i686/cmov/libdl.so.2 (0xf753e000)
libpthread.so.0 => /lib/i386-linux-gnu/i686/cmov/libpthread.so.0 (0xf7522000)
libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xf7430000)
libm.so.6 => /lib/i386-linux-gnu/i686/cmov/libm.so.6 (0xf73ea000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xf73cd000)
libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xf721f000)
librt.so.1 => /lib/i386-linux-gnu/i686/cmov/librt.so.1 (0xf7216000)
libltdl.so.7 => /usr/lib/i386-linux-gnu/libltdl.so.7 (0xf720a000)
/lib/ld-linux.so.2 (0xf7766000)
Как вы могли видеть, здесь нет пропавших без вести. Что мне не хватает?
Наконец, я установил 32-битную версию Debian. Как мне показалось, проблема заключалась в драйвере IBM I Access Driver 64-bit версии. Я просто выполнил те же шаги на новой установке, и она работает как шарм. Надеюсь, это поможет кому-то еще.
Это дубликат # 21286589. Просто потому, что у вас нет NULL
Значение не означает, что вы не столкнетесь с проблемами при использовании несовпадающего ABI.
Проблема здесь в том, что старый драйвер устанавливает только 32-битное значение 64-битного индикатора, а PHP считывает целые 64-битные. Здесь PHP видит значение 140707423584261, которое 0x7FF900000005
в шестнадцатеричном виде Вы можете увидеть последние 4 байта 0x00000005
который равен 5 и должен быть длиной возвращаемых фактических данных. Все остальное — мусор, потому что драйвер не изменил эти байты.
Как я уже упоминал в своем ответе на Linux odbc Неустранимая ошибка: допустимый объем памяти, вам потребуется получить новый драйвер ODBC из пакета приложений Linux IBM i Access Client Solutions. Этот драйвер следует полному 64-битному ABI, который unixODBC использует с 2.2.14. Новый пакет драйверов также содержит пакеты Debian .deb, поэтому практически все шаги в блоге, на который вы ссылались, больше не нужны.
Других решений пока нет …