Ошибка ORA-12899 в поле CHAR(1), но я посылаю только 'C'
Моя база данных Oracle возвращает ошибку:
ORA-12899 - слишком большое значение для столбца TIT.ESTADO_CIVIL (фактическое: 2, максимальное: 1)
Но я очень уверен, что отправленное значение является уникальным символом 'C'.
Кто-нибудь знает, почему это происходит?
(Я использую C# с ODP.NET)
2 ответа
"Символ C# имеет 16 бит; поиск в Google говорит мне, что типы Oracle CHAR - 8 бит".
Есть несколько способов справиться с этим. Лучшим решением было бы исправить базу данных, чтобы она использовала семантику символов.
alter system set nls_length_semantics = char
/
Поскольку это имеет серьезные последствия, вы должны быть уверены, что это решит вашу проблему. Измените свою таблицу, чтобы использовать семантику символов, и посмотрите, удаляет ли она исключения ORA-12899.
SQL> create table t69 (col1 char(1 byte))
2 /
Table created.
SQL> desc t69
Name Null? Type
------------- -------- ----------------
COL1 CHAR(1)
SQL> alter table t69 modify col1 char(1 char)
2 /
Table altered.
SQL> desc t69
Name Null? Type
------------- -------- ----------------
COL1 CHAR(1 CHAR)
SQL>
В документации много полезной информации о глобализации и наборах символов. Вы не говорите, какую версию базы данных вы используете, поэтому вот ссылка на 9i документы по семантике длины.
Исправление на уровне базы данных кажется наилучшей идеей, согласно принятому ответу, поскольку оно позволяет избежать неожиданного поведения.
Однако, если вы не хотите исправлять (или не можете получить доступ) на уровне базы данных, у меня сработало два способа. Я не уверен насчет второго, но хотел бы поделиться им, если кто-то посчитает его полезным / сможет объяснить.
Моя проблема
- Хранимая процедура Oracle принимает входной параметр типа
char (1 byte)
, который используется для установки значенияchar (1 byte)
колонка я использую
System.Data.OracleClient.OracleCommand
IDbDataParameter parm = command.CreateParameter(); parm.ParameterName = "myname"; parm.ParameterValue = 'A'; // a C# (16 bit) char
Это поражает value too large for column
ошибка, которую упоминает оригинальный постер.
Решение 1
Переопределить OracleType
вручную после установки значения:
((OracleParameter)parm).OracleType = OracleType.Char;
Решение 2
Чуть более хитроумно - просто используйте строку (я не понимаю, почему это работает, поэтому не стоит полагаться на нее):
parm.ParameterValue = "A"; // "A" instead of 'A'