2012-03-09 3 views
2

У меня есть следующие проблемы:акцентировано символ занимает более один символ

я должен хранить в базе данных данных, который вставляется в поле ввода внутри формы. Я подтверждаю, что данные на этом входе не превышают 40 символов.

Проблема заключается в том, что если я вставляю текст с 40 символами, но один из них акцентирован, то, очевидно, проверка не показывает никаких ошибок, но когда она будет храниться в базе данных, будет выведено следующее исключение :

ORA-12899: значение слишком велики для столбца "DBUser" "СТОЛА" "кОЛОННЫ".. (фактическая: 41, максимум: 40)

, кажется, что акцентировано символ занимает более одного полукокс в базе данных.

Я предполагаю, что это связано с кодировкой, но я понятия не имею, с чего начать искать. есть идеи?

спасибо !!

+0

Что такое кодировка символов вашей базы данных? –

+0

параметр NLS_CHARACTERSET установлен в AL32UTF8 – Neets

+0

Можете ли вы опубликовать код, который используется для проверки ввода, плюс вы можете привести пример проблемных символов. – alykhalid

ответ

4

Use NVARCHAR2 as type для столбца или сделать столбец как минимум в шесть раз более широким, чем самый длинный вход (один символ Юникода может составлять не более 6 байтов с кодировкой UTF-8).

+1

NVARCHAR2 - это, безусловно, путь. Конечно, переключение типов данных, подобных этому, не является простым процессом. Проблема возникает в плохом дизайне: выбор символа Unicode без создания модели данных, которая ее поддерживает. Это было бы подходящее время, чтобы указать на эту статью * Джоэл Спольски, покровителем SO: http://www.joelonsoftware.com/articles/Unicode.html – APC

+0

FWIW, подход, который я использовал в прошлом, - это бюджет для определенной части символов, отличных от ASCII. Если вы строите сайт, который будет обрабатывать целый ряд европейских языков, то вам, вероятно, нужно разрешить примерно 10% персонажей, которые будут акцентированы (в статье с первой страницы Le Monde я просто измерил ее на 3,4 %; 10% имеет большой запас высоты). Итак, если у вас есть поле с 40 символами, допустимо, чтобы оно составляло 44 байта. –

+1

Хотя, честно говоря, учитывая, что Oracle и другие современные базы данных хранят строки, я бы, вероятно, просто объявлял каждый столбец (n) varchar длиной 4000 символов и выполнял всю проверку на прикладном уровне. –

2

Использовать CHAR, как предложено @Adam Musch. Вы действительно не хотите использовать NVARCHAR2 или угадать возможное количество байтов.

create table my_table1(small_string varchar2(1 byte)); 
create table my_table2(small_string varchar2(1 char)); 

insert into my_table1 values('Þ'); --"ORA-12899: value too large for ..." 
insert into my_table2 values('Þ'); --works fine 

Вы можете явно задать длину семантику либо BYTE или CHAR, но, скорее всего, вы используете значение по умолчанию, BYTE. Значение по умолчанию определяется NLS_LENGTH_SEMANTICS. Проверьте значение с помощью этого запроса:

select * from v$parameter where name = 'nls_length_semantics'; 

Вы можете изменить значение по умолчанию с помощью инструкции ниже. (Хотя вы, вероятно, забыли изменить этот параметр, это надежнее явно использование CHAR в вашем DDL.)

alter session set nls_length_semantics = char; 

Этот параметр не изменяет существующие объекты, вам необходимо вручную изменить таблицу с SQL:

alter table my_table1 modify (small_string varchar2(1 char)); 
Смежные вопросы