Если я прав, вам лучше перейти на оракул 12. Позвольте мне объяснить:
Oracle (до версии 11 включительно) имеет предел HARD 4000 BYTES для столбцов char / varchar, и этот предел не может быть преодолен путем простого объявления столбца как "varchar2 (4000) CHAR) ".
если в вашей базе данных используется многобайтовый набор символов, этот предел все еще остается в силе, поэтому вы сможете хранить 4000 символов только при соблюдении этих двух условий:
- в вашей кодировке есть символы, которые занимают только один байт
строка, которую вы хотите сохранить, состоит только из символов, закодированных в один байт
Например: если ваш набор символов в базе данных - UTF8, символ «А» занимает один байт, но символу «а» требуется два байта:
| Bytes required |Bytes required | Bytes required
string | if database charset |if database charset | if database charset
| is ASCII |is UTF8 | is UTF16
--------- |-------------------------------------------------------------------
"A" | 1 byte | 1 bytes | 2 bytes
"à" | 1 byte | 2 bytes | 2 bytes
"àA" | 2 byte | 3 bytes | 4 bytes
поэтому в столбце VARCHAR2 (4000 CHAR) в базе данных UTF8 вы сможете хранить строку, состоящую из 4000 символов «A», но если вы используете 4000 символов «à», она будет ограничена 2000 символами : в UTF8 любой символ, чей код unicode number> = 128 (то есть: это не ASCII-символ), занимает несколько байтов. в UTF16 любой символ съедает как минимум 2 байта.
Глядя на описываемые вами симптомы (и на ваше имя), я думаю, что вы не используете однобайтовый набор символов ... и я также думаю, что большинству используемых символов требуется как минимум два байта, так вот причина фактического ограничения в 2000 символов: вы сталкиваетесь с жестким ограничением в 4000 байтов.
Я думаю, что единственное «простое» решение для вас - это обновить базу данных до оракула 12, где этот жесткий предел может быть увеличен до 32000 байт (AFAIK, он не делает это «из коробки»: вам нужно соответственно настроить его при создании базы данных).
если вы создадите базу данных oracle 12 с повышенным пределом, ваши столбцы varchar2 (4000 CHAR) больше не будут соответствовать жесткому пределу.
Помните также, что когда вы обычно объявляете столбец как VARCHAR2 (4000), oracle по умолчанию интерпретирует его как VARCHAR2 (4000 BYTE). это значение по умолчанию можно изменить, выполнив в течение сеанса следующее:
alter session set NLS_LENGTH_SEMANTICS='CHAR'
его TEORICALLY можно установить на уровне экземпляра для всей базы данных и всего сеанса, , но оракул предупреждает вас НЕ делать этого, потому что система будет некорректно работать , поэтому придерживайтесь его использования на уровне сеанса.
Надеюсь, это поможет.
P.S. Может быть, вы найдете полезную подсказку:
В моей базе данных я написал триггер "после входа в систему", который выполняется автоматически, который изменяет сеанс только для пользователя (ей) моего приложения
CREATE OR REPLACE TRIGGER TRG_MYAPP_AFTER_LOGON
AFTER LOGON on database
declare
function IsMyAppUser return boolean is
cnt number;
begin
-- if the user is the owner of the schema, all its commands are expected
-- to use the "char" length semantics
if user = 'MYAPP' then
return true;
end if;
--- this is specific to my app: I have a table that lists the login names
--- of the users who have been created only with the purpose of using the app
select count(*) into cnt
from my_app_users u
where u.usr_login=user
and ROWNUM=1;
return cnt>0;
end;
BEGIN
if IsMyAppUser then
execute immediate 'alter session set nls_length_semantics = ''CHAR''';
end if;
END TRG_QBF_AFTER_LOGON;