снизит максимальную емкость до 2000 символов. Единственное за что я могу предсказать, подойдет ли данная строка. В этом суть или я что-то упустил?
держиваю PHP-приложение с Oracle Backend (функции OCI8). Приложение разработано с использованием Oracle 10g XE и развернуто на любой версии, которой владеет клиент.
Приложение обрабатывает однобайтовый текст (ISO-8859-15), и у меня никогда не было проблем при разработке сЗападноевропейский издание Oracle XE. Тем не менее, я недавно установилуниверсальный и у меня возникают проблемы при вставке больших строк с не-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 может вызвать другие проблемы (почти все наши клиенты имеют однобайтовые базы данных).