Я поддерживаю PHP-приложение с бэкэндом Oracle (функции OCI8).Приложение разработано с использованием Oracle 10g XE и развернуто на любой версии, которой владеет клиент.
Приложение обрабатывает однобайтовый текст (ISO-8859-15), и у меня никогда не было проблем при разработке с Западноевропейская редакция Oracle XE.Тем не менее, я недавно установил Universal , и у меня возникают проблемы при вставке больших строк с не-ASCII символами.Эта версия устанавливает NLS_CHARACTERSET = AL32UTF8
;так как мое приложение использует WE8ISO8859P15
Oracle молча преобразует мои входные данные из ISO-8859-15 в UTF-8 (что нормально).Но кажется, что некоторые проверки размера идут не так: строка с 1500 €
символами (1500 байт в ISO-8889-15, 4500 байт в UTF-8), кажется, переполняет столбец VARCHAR2(4000 CHAR)
.
Я создал эту тестовую таблицу:
CREATE TABLE FOO (
FOO_ID NUMBER NOT NULL ENABLE,
DATA_BYTE VARCHAR2(4000 BYTE),
DATA_CHAR VARCHAR2(4000 CHAR),
CONSTRAINT FOO_PK PRIMARY KEY (FOO_ID)
);
Проблема может быть воспроизведена с помощью этого кода:
<?php
$connection = oci_connect(DB_USER, DB_PASS, DB_CONN_STRING, 'WE8ISO8859P15');
if( !$connection ){
$e = oci_error();
die(htmlspecialchars($e['message']));
}
$id = 1;
$data = str_repeat('€', 1500);
$sql = 'INSERT INTO FOO (FOO_ID, DATA_CHAR) ' .
'VALUES (:id, :data)';
$res = oci_parse($connection, $sql);
if(!$res){
$e = oci_error();
die(htmlspecialchars($e['message']));
}
if(!oci_bind_by_name($res, ':id', $id)){
$e = oci_error();
die(htmlspecialchars($e['message']));
}
if(!oci_bind_by_name($res, ':data', $data)){
$e = oci_error();
die(htmlspecialchars($e['message']));
}
if(!oci_execute($res, OCI_COMMIT_ON_SUCCESS)){
$e = oci_error();
die(htmlspecialchars($e['message']));
}
... который вызывает:
Предупреждение: oci_execute (): ORA-01461: все равно длинно, долго, долго, долго, долго
Это та же ошибка, что и я, когда я пытаюсь вставить строку символа 4001.Этого не произойдет, если я вставлю xxx...
вместо €€€
, и этого не произойдет, если я сохраню свой сценарий как UTF-8 и подключусь так:
<?php
$connection = oci_connect(DB_USER, DB_PASS, DB_CONN_STRING, 'AL32UTF8');
[ Обновление: Мой тест был ошибочным.Использование UTF-8 не исключает ORA-01461]
Как я могу решить эту проблему?Параметр базы данных NLS_CHARACTERSET - это не то, чем я управляю , и переключение моего приложения на UTF-8 может вызвать другие проблемы (почти у всех наших клиентов есть однобайтовые базы данных).