💢 OCI8: проблемы с переходом на PHP7

Ещё в копилку проблем с ПХП7: если при привязке переменных в Оракле (bind) поля типа LONG/LOB не находятся в конце списка, то вы получите ошибку ORA-24816. Все столбцы таких типов должны быть привязаны последними, в общей куче. Мы пока столкнулись с проблемой только при сохранении (тестирование пока идёт), в итоге в сохраняющем методе модели пересортировали привязки, основываясь на описании модели.

Комментарии 13

Gintonic № 1

Доброго дня,

Мы пока столкнулись с проблемой только при сохранении (тестирование пока идёт), в итоге в сохраняющем методе модели пересортировали привязки, основываясь на описании модели.

Можете привести пример запроса? Это выражение UPDATE или процедура/функция с входными параметрами (или и то и другое)?

Евгений Степанищев (bolknote.ru) автор № 3
Комментарий для Gintonic:

В нашем случае это UPDATE или INSERT (не знаю точно), в SELECT пока не встретили.
Сергей № 5
Это не бага, это фича
http://docs.oracle.com/cd/E11882_01/appdev … LNOCI16372

A special consideration applies on the maximum size of bind variables that are neither LONG or LOB, but that appear after any LOB or LONG bind variable in the SQL statement. You receive an ORA-24816 error from Oracle Database if the maximum size for such bind variables exceeds 4000 bytes. To avoid this error, you must set OCI_ATTR_MAXDATA_SIZE to 4000 bytes for any such binds whose maximum size may exceed 4000 bytes on the server side after character set conversion. Alternatively, reorder the binds so that such binds are placed before any LONG or LOBs in the bind list.

Если у тебя varchar2(4000) и UTF, то
When a client connects to a multibyte database (AL32UTF8 for example) and the string , once converted to the multibyte database encoding becomes longer than 4000 BYTES Oracle transforms this internally into a LONG as the data is longer than the 4000 bytes max value for Varchar2.
OCI has a requirement that any LOB and LONG needs to be the last of the bind list, this includes that «real» LONG/LOB need to be the last and after any VARCHAR2 that is expanded to over 4000 BYTE due to the characterset conversion
Евгений Степанищев (bolknote.ru) автор № 6
Почему-то эта «фича» проявляется только на ПХП7, на предыдущих версиях годами проблем не было. Видимо драйвер это как-то сам разруливал.
Сергей № 7
Тут я только гадать могу:
1. Свежая тестовая база создана в уникоде, а предыдущая нет?
2. Предыдущий драйвер ставил OCI_ATTR_MAXDATA_SIZE?
Сергей № 9
Комментарий для Евгения Степанищева:

Всё страньше и страньше…
Причем вопрос, с мое кочки зрения, не почему не работает в php7 (не должно работать), а как работало в php5? Единственное, что приходит в голову — ошибка в реализации ошибки :). Или наглая установка OCI_ATTR_MAXDATA_SIZE за что надо бить сапогами.
Но по php я совсем не специалист.
Кстати, в Oracle 12 ограничение осталось.
Евгений Степанищев (bolknote.ru) автор № 10
Комментарий для Сергей:

Для меня эта ситуация — баг. Годами нормально всё работало, всегда, во всех ситуациях, а тут что-то поломали. По мне так надо вернуть как было.
Gintonic № 11

Не прошло и 3-х месяцев, как запилили фикс, см. комментарии на https://bugs.php.net/bug.php?id=72524
Как раз сегодня запулили pull-request в master,
http://git.php.net/?p=php-src.git%26a=sear … %26s=72524

39 min ago Christoph M. Becker Merge branch 'pull-request/1997' master

так что можно ожидать, что в версии 7.0.11 или какой-то ближайшей это выкатят

Gintonic № 12
похоже, обрадовался рано, речь в исправлении идёт только про биндинг NULL-значений после LONG/LOB, а не про любые.